// SPDX-License-Identifier: GPL-2.0
/*
 * Thunderbolt XDomain discovery protocol support
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/prandom.h>
#include <linux/string_helpers.h>
#include <linux/utsname.h>
#include <linux/uuid.h>
#include <linux/workqueue.h>

#include "tb.h"

#define XDOMAIN_SHORT_TIMEOUT			100	/* ms */
#define XDOMAIN_DEFAULT_TIMEOUT			1000	/* ms */
#define XDOMAIN_BONDING_TIMEOUT			10000	/* ms */
#define XDOMAIN_RETRIES				10
#define XDOMAIN_DEFAULT_MAX_HOPID		15

enum {
	XDOMAIN_STATE_INIT,
	XDOMAIN_STATE_UUID,
	XDOMAIN_STATE_LINK_STATUS,
	XDOMAIN_STATE_LINK_STATE_CHANGE,
	XDOMAIN_STATE_LINK_STATUS2,
	XDOMAIN_STATE_BONDING_UUID_LOW,
	XDOMAIN_STATE_BONDING_UUID_HIGH,
	XDOMAIN_STATE_PROPERTIES,
	XDOMAIN_STATE_ENUMERATED,
	XDOMAIN_STATE_ERROR,
};

static const char * const state_names[] = {
	[XDOMAIN_STATE_INIT] = "INIT",
	[XDOMAIN_STATE_UUID] = "UUID",
	[XDOMAIN_STATE_LINK_STATUS] = "LINK_STATUS",
	[XDOMAIN_STATE_LINK_STATE_CHANGE] = "LINK_STATE_CHANGE",
	[XDOMAIN_STATE_LINK_STATUS2] = "LINK_STATUS2",
	[XDOMAIN_STATE_BONDING_UUID_LOW] = "BONDING_UUID_LOW",
	[XDOMAIN_STATE_BONDING_UUID_HIGH] = "BONDING_UUID_HIGH",
	[XDOMAIN_STATE_PROPERTIES] = "PROPERTIES",
	[XDOMAIN_STATE_ENUMERATED] = "ENUMERATED",
	[XDOMAIN_STATE_ERROR] = "ERROR",
};

struct xdomain_request_work {
	struct work_struct work;
	struct tb_xdp_header *pkg;
	size_t pkg_len;
	struct tb *tb;
};

static bool tb_xdomain_enabled = true;
module_param_named(xdomain, tb_xdomain_enabled, bool, 0444);
MODULE_PARM_DESC(xdomain, "allow XDomain protocol (default: true)");

/*
 * Serializes access to the properties and protocol handlers below. If
 * you need to take both this lock and the struct tb_xdomain lock, take
 * this one first.
 */
static DEFINE_MUTEX(xdomain_lock);

/* Properties exposed to the remote domains */
static struct tb_property_dir *xdomain_property_dir;
static u32 xdomain_property_block_gen;

/* Additional protocol handlers */
static LIST_HEAD(protocol_handlers);

/* UUID for XDomain discovery protocol: b638d70e-42ff-40bb-97c2-90e2c0b2ff07 */
static const uuid_t tb_xdp_uuid =
	UUID_INIT(0xb638d70e, 0x42ff, 0x40bb,
		  0x97, 0xc2, 0x90, 0xe2, 0xc0, 0xb2, 0xff, 0x07);

bool tb_is_xdomain_enabled(void)
{
	return tb_xdomain_enabled && tb_acpi_is_xdomain_allowed();
}

static bool tb_xdomain_match(const struct tb_cfg_request *req,
			     const struct ctl_pkg *pkg)
{
	switch (pkg->frame.eof) {
	case TB_CFG_PKG_ERROR:
		return true;

	case TB_CFG_PKG_XDOMAIN_RESP: {
		const struct tb_xdp_header *res_hdr = pkg->buffer;
		const struct tb_xdp_header *req_hdr = req->request;

		if (pkg->frame.size < req->response_size / 4)
			return false;

		/* Make sure route matches */
		if ((res_hdr->xd_hdr.route_hi & ~BIT(31)) !=
		     req_hdr->xd_hdr.route_hi)
			return false;
		if ((res_hdr->xd_hdr.route_lo) != req_hdr->xd_hdr.route_lo)
			return false;

		/* Check that the XDomain protocol matches */
		if (!uuid_equal(&res_hdr->uuid, &req_hdr->uuid))
			return false;

		return true;
	}

	default:
		return false;
	}
}

static bool tb_xdomain_copy(struct tb_cfg_request *req,
			    const struct ctl_pkg *pkg)
{
	size_t len = min_t(size_t, pkg->frame.size, req->response_size);

	memcpy(req->response, pkg->buffer, len);
	req->result.err = 0;
	return true;
}

static void response_ready(void *data)
{
	tb_cfg_request_put(data);
}

static int __tb_xdomain_response(struct tb_ctl *ctl, const void *response,
				 size_t size, enum tb_cfg_pkg_type type)
{
	struct tb_cfg_request *req;

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

	req->match = tb_xdomain_match;
	req->copy = tb_xdomain_copy;
	req->request = response;
	req->request_size = size;
	req->request_type = type;

	return tb_cfg_request(ctl, req, response_ready, req);
}

/**
 * tb_xdomain_response() - Send a XDomain response message
 * @xd: XDomain to send the message
 * @response: Response to send
 * @size: Size of the response
 * @type: PDF type of the response
 *
 * This can be used to send a XDomain response message to the other
 * domain. No response for the message is expected.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_xdomain_response(struct tb_xdomain *xd, const void *response,
			size_t size, enum tb_cfg_pkg_type type)
{
	return __tb_xdomain_response(xd->tb->ctl, response, size, type);
}
EXPORT_SYMBOL_GPL(tb_xdomain_response);

static int __tb_xdomain_request(struct tb_ctl *ctl, const void *request,
	size_t request_size, enum tb_cfg_pkg_type request_type, void *response,
	size_t response_size, enum tb_cfg_pkg_type response_type,
	unsigned int timeout_msec)
{
	struct tb_cfg_request *req;
	struct tb_cfg_result res;

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

	req->match = tb_xdomain_match;
	req->copy = tb_xdomain_copy;
	req->request = request;
	req->request_size = request_size;
	req->request_type = request_type;
	req->response = response;
	req->response_size = response_size;
	req->response_type = response_type;

	res = tb_cfg_request_sync(ctl, req, timeout_msec);

	tb_cfg_request_put(req);

	return res.err == 1 ? -EIO : res.err;
}

/**
 * tb_xdomain_request() - Send a XDomain request
 * @xd: XDomain to send the request
 * @request: Request to send
 * @request_size: Size of the request in bytes
 * @request_type: PDF type of the request
 * @response: Response is copied here
 * @response_size: Expected size of the response in bytes
 * @response_type: Expected PDF type of the response
 * @timeout_msec: Timeout in milliseconds to wait for the response
 *
 * This function can be used to send XDomain control channel messages to
 * the other domain. The function waits until the response is received
 * or when timeout triggers. Whichever comes first.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
	size_t request_size, enum tb_cfg_pkg_type request_type,
	void *response, size_t response_size,
	enum tb_cfg_pkg_type response_type, unsigned int timeout_msec)
{
	return __tb_xdomain_request(xd->tb->ctl, request, request_size,
				    request_type, response, response_size,
				    response_type, timeout_msec);
}
EXPORT_SYMBOL_GPL(tb_xdomain_request);

static inline void tb_xdp_fill_header(struct tb_xdp_header *hdr, u64 route,
	u8 sequence, enum tb_xdp_type type, size_t size)
{
	u32 length_sn;

	length_sn = (size - sizeof(hdr->xd_hdr)) / 4;
	length_sn |= (sequence << TB_XDOMAIN_SN_SHIFT) & TB_XDOMAIN_SN_MASK;

	hdr->xd_hdr.route_hi = upper_32_bits(route);
	hdr->xd_hdr.route_lo = lower_32_bits(route);
	hdr->xd_hdr.length_sn = length_sn;
	hdr->type = type;
	memcpy(&hdr->uuid, &tb_xdp_uuid, sizeof(tb_xdp_uuid));
}

static int tb_xdp_handle_error(const struct tb_xdp_error_response *res)
{
	if (res->hdr.type != ERROR_RESPONSE)
		return 0;

	switch (res->error) {
	case ERROR_UNKNOWN_PACKET:
	case ERROR_UNKNOWN_DOMAIN:
		return -EIO;
	case ERROR_NOT_SUPPORTED:
		return -EOPNOTSUPP;
	case ERROR_NOT_READY:
		return -EAGAIN;
	default:
		break;
	}

	return 0;
}

static int tb_xdp_uuid_request(struct tb_ctl *ctl, u64 route, int retry,
			       uuid_t *uuid, u64 *remote_route)
{
	struct tb_xdp_uuid_response res;
	struct tb_xdp_uuid req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4, UUID_REQUEST,
			   sizeof(req));

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req),
				   TB_CFG_PKG_XDOMAIN_REQ, &res, sizeof(res),
				   TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	ret = tb_xdp_handle_error(&res.err);
	if (ret)
		return ret;

	uuid_copy(uuid, &res.src_uuid);
	*remote_route = (u64)res.src_route_hi << 32 | res.src_route_lo;

	return 0;
}

static int tb_xdp_uuid_response(struct tb_ctl *ctl, u64 route, u8 sequence,
				const uuid_t *uuid)
{
	struct tb_xdp_uuid_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence, UUID_RESPONSE,
			   sizeof(res));

	uuid_copy(&res.src_uuid, uuid);
	res.src_route_hi = upper_32_bits(route);
	res.src_route_lo = lower_32_bits(route);

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_error_response(struct tb_ctl *ctl, u64 route, u8 sequence,
				 enum tb_xdp_error error)
{
	struct tb_xdp_error_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence, ERROR_RESPONSE,
			   sizeof(res));
	res.error = error;

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
	const uuid_t *src_uuid, const uuid_t *dst_uuid, int retry,
	u32 **block, u32 *generation)
{
	struct tb_xdp_properties_response *res;
	struct tb_xdp_properties req;
	u16 data_len, len;
	size_t total_size;
	u32 *data = NULL;
	int ret;

	total_size = sizeof(*res) + TB_XDP_PROPERTIES_MAX_DATA_LENGTH * 4;
	res = kzalloc(total_size, GFP_KERNEL);
	if (!res)
		return -ENOMEM;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4, PROPERTIES_REQUEST,
			   sizeof(req));
	memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid));
	memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid));

	data_len = 0;

	do {
		ret = __tb_xdomain_request(ctl, &req, sizeof(req),
					   TB_CFG_PKG_XDOMAIN_REQ, res,
					   total_size, TB_CFG_PKG_XDOMAIN_RESP,
					   XDOMAIN_DEFAULT_TIMEOUT);
		if (ret)
			goto err;

		ret = tb_xdp_handle_error(&res->err);
		if (ret)
			goto err;

		/*
		 * Package length includes the whole payload without the
		 * XDomain header. Validate first that the package is at
		 * least size of the response structure.
		 */
		len = res->hdr.xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK;
		if (len < sizeof(*res) / 4) {
			ret = -EINVAL;
			goto err;
		}

		len += sizeof(res->hdr.xd_hdr) / 4;
		len -= sizeof(*res) / 4;

		if (res->offset != req.offset) {
			ret = -EINVAL;
			goto err;
		}

		/*
		 * First time allocate block that has enough space for
		 * the whole properties block.
		 */
		if (!data) {
			data_len = res->data_length;
			if (data_len > TB_XDP_PROPERTIES_MAX_LENGTH) {
				ret = -E2BIG;
				goto err;
			}

			data = kcalloc(data_len, sizeof(u32), GFP_KERNEL);
			if (!data) {
				ret = -ENOMEM;
				goto err;
			}
		}

		if (req.offset + len > data_len)
			len = data_len - req.offset;
		memcpy(data + req.offset, res->data, len * 4);
		req.offset += len;
	} while (!data_len || req.offset < data_len);

	*block = data;
	*generation = res->generation;

	kfree(res);

	return data_len;

err:
	kfree(data);
	kfree(res);

	return ret;
}

static int tb_xdp_properties_response(struct tb *tb, struct tb_ctl *ctl,
	struct tb_xdomain *xd, u8 sequence, const struct tb_xdp_properties *req)
{
	struct tb_xdp_properties_response *res;
	size_t total_size;
	u16 len;
	int ret;

	/*
	 * Currently we expect all requests to be directed to us. The
	 * protocol supports forwarding, though which we might add
	 * support later on.
	 */
	if (!uuid_equal(xd->local_uuid, &req->dst_uuid)) {
		tb_xdp_error_response(ctl, xd->route, sequence,
				      ERROR_UNKNOWN_DOMAIN);
		return 0;
	}

	mutex_lock(&xd->lock);

	if (req->offset >= xd->local_property_block_len) {
		mutex_unlock(&xd->lock);
		return -EINVAL;
	}

	len = xd->local_property_block_len - req->offset;
	len = min_t(u16, len, TB_XDP_PROPERTIES_MAX_DATA_LENGTH);
	total_size = sizeof(*res) + len * 4;

	res = kzalloc(total_size, GFP_KERNEL);
	if (!res) {
		mutex_unlock(&xd->lock);
		return -ENOMEM;
	}

	tb_xdp_fill_header(&res->hdr, xd->route, sequence, PROPERTIES_RESPONSE,
			   total_size);
	res->generation = xd->local_property_block_gen;
	res->data_length = xd->local_property_block_len;
	res->offset = req->offset;
	uuid_copy(&res->src_uuid, xd->local_uuid);
	uuid_copy(&res->dst_uuid, &req->src_uuid);
	memcpy(res->data, &xd->local_property_block[req->offset], len * 4);

	mutex_unlock(&xd->lock);

	ret = __tb_xdomain_response(ctl, res, total_size,
				    TB_CFG_PKG_XDOMAIN_RESP);

	kfree(res);
	return ret;
}

static int tb_xdp_properties_changed_request(struct tb_ctl *ctl, u64 route,
					     int retry, const uuid_t *uuid)
{
	struct tb_xdp_properties_changed_response res;
	struct tb_xdp_properties_changed req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4,
			   PROPERTIES_CHANGED_REQUEST, sizeof(req));
	uuid_copy(&req.src_uuid, uuid);

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req),
				   TB_CFG_PKG_XDOMAIN_REQ, &res, sizeof(res),
				   TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	return tb_xdp_handle_error(&res.err);
}

static int
tb_xdp_properties_changed_response(struct tb_ctl *ctl, u64 route, u8 sequence)
{
	struct tb_xdp_properties_changed_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence,
			   PROPERTIES_CHANGED_RESPONSE, sizeof(res));
	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_link_state_status_request(struct tb_ctl *ctl, u64 route,
					    u8 sequence, u8 *slw, u8 *tlw,
					    u8 *sls, u8 *tls)
{
	struct tb_xdp_link_state_status_response res;
	struct tb_xdp_link_state_status req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, sequence, LINK_STATE_STATUS_REQUEST,
			   sizeof(req));

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req), TB_CFG_PKG_XDOMAIN_REQ,
				   &res, sizeof(res), TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	ret = tb_xdp_handle_error(&res.err);
	if (ret)
		return ret;

	if (res.status != 0)
		return -EREMOTEIO;

	*slw = res.slw;
	*tlw = res.tlw;
	*sls = res.sls;
	*tls = res.tls;

	return 0;
}

static int tb_xdp_link_state_status_response(struct tb *tb, struct tb_ctl *ctl,
					     struct tb_xdomain *xd, u8 sequence)
{
	struct tb_xdp_link_state_status_response res;
	struct tb_port *port = tb_xdomain_downstream_port(xd);
	u32 val[2];
	int ret;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, xd->route, sequence,
			   LINK_STATE_STATUS_RESPONSE, sizeof(res));

	ret = tb_port_read(port, val, TB_CFG_PORT,
			   port->cap_phy + LANE_ADP_CS_0, ARRAY_SIZE(val));
	if (ret)
		return ret;

	res.slw = (val[0] & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >>
			LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT;
	res.sls = (val[0] & LANE_ADP_CS_0_SUPPORTED_SPEED_MASK) >>
			LANE_ADP_CS_0_SUPPORTED_SPEED_SHIFT;
	res.tls = val[1] & LANE_ADP_CS_1_TARGET_SPEED_MASK;
	res.tlw = (val[1] & LANE_ADP_CS_1_TARGET_WIDTH_MASK) >>
			LANE_ADP_CS_1_TARGET_WIDTH_SHIFT;

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_link_state_change_request(struct tb_ctl *ctl, u64 route,
					    u8 sequence, u8 tlw, u8 tls)
{
	struct tb_xdp_link_state_change_response res;
	struct tb_xdp_link_state_change req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, sequence, LINK_STATE_CHANGE_REQUEST,
			   sizeof(req));
	req.tlw = tlw;
	req.tls = tls;

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req), TB_CFG_PKG_XDOMAIN_REQ,
				   &res, sizeof(res), TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	ret = tb_xdp_handle_error(&res.err);
	if (ret)
		return ret;

	return res.status != 0 ? -EREMOTEIO : 0;
}

static int tb_xdp_link_state_change_response(struct tb_ctl *ctl, u64 route,
					     u8 sequence, u32 status)
{
	struct tb_xdp_link_state_change_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence, LINK_STATE_CHANGE_RESPONSE,
			   sizeof(res));

	res.status = status;

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

/**
 * tb_register_protocol_handler() - Register protocol handler
 * @handler: Handler to register
 *
 * This allows XDomain service drivers to hook into incoming XDomain
 * messages. After this function is called the service driver needs to
 * be able to handle calls to callback whenever a package with the
 * registered protocol is received.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_register_protocol_handler(struct tb_protocol_handler *handler)
{
	if (!handler->uuid || !handler->callback)
		return -EINVAL;
	if (uuid_equal(handler->uuid, &tb_xdp_uuid))
		return -EINVAL;

	mutex_lock(&xdomain_lock);
	list_add_tail(&handler->list, &protocol_handlers);
	mutex_unlock(&xdomain_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(tb_register_protocol_handler);

/**
 * tb_unregister_protocol_handler() - Unregister protocol handler
 * @handler: Handler to unregister
 *
 * Removes the previously registered protocol handler.
 */
void tb_unregister_protocol_handler(struct tb_protocol_handler *handler)
{
	mutex_lock(&xdomain_lock);
	list_del_init(&handler->list);
	mutex_unlock(&xdomain_lock);
}
EXPORT_SYMBOL_GPL(tb_unregister_protocol_handler);

static void update_property_block(struct tb_xdomain *xd)
{
	mutex_lock(&xdomain_lock);
	mutex_lock(&xd->lock);
	/*
	 * If the local property block is not up-to-date, rebuild it now
	 * based on the global property template.
	 */
	if (!xd->local_property_block ||
	    xd->local_property_block_gen < xdomain_property_block_gen) {
		struct tb_property_dir *dir;
		int ret, block_len;
		u32 *block;

		dir = tb_property_copy_dir(xdomain_property_dir);
		if (!dir) {
			dev_warn(&xd->dev, "failed to copy properties\n");
			goto out_unlock;
		}

		/* Fill in non-static properties now */
		tb_property_add_text(dir, "deviceid", utsname()->nodename);
		tb_property_add_immediate(dir, "maxhopid", xd->local_max_hopid);

		ret = tb_property_format_dir(dir, NULL, 0);
		if (ret < 0) {
			dev_warn(&xd->dev, "local property block creation failed\n");
			tb_property_free_dir(dir);
			goto out_unlock;
		}

		block_len = ret;
		block = kcalloc(block_len, sizeof(*block), GFP_KERNEL);
		if (!block) {
			tb_property_free_dir(dir);
			goto out_unlock;
		}

		ret = tb_property_format_dir(dir, block, block_len);
		if (ret) {
			dev_warn(&xd->dev, "property block generation failed\n");
			tb_property_free_dir(dir);
			kfree(block);
			goto out_unlock;
		}

		tb_property_free_dir(dir);
		/* Release the previous block */
		kfree(xd->local_property_block);
		/* Assign new one */
		xd->local_property_block = block;
		xd->local_property_block_len = block_len;
		xd->local_property_block_gen = xdomain_property_block_gen;
	}

out_unlock:
	mutex_unlock(&xd->lock);
	mutex_unlock(&xdomain_lock);
}

static void start_handshake(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_INIT;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT));
}

/* Can be called from state_work */
static void __stop_handshake(struct tb_xdomain *xd)
{
	cancel_delayed_work_sync(&xd->properties_changed_work);
	xd->properties_changed_retries = 0;
	xd->state_retries = 0;
}

static void stop_handshake(struct tb_xdomain *xd)
{
	cancel_delayed_work_sync(&xd->state_work);
	__stop_handshake(xd);
}

static void tb_xdp_handle_request(struct work_struct *work)
{
	struct xdomain_request_work *xw = container_of(work, typeof(*xw), work);
	const struct tb_xdp_header *pkg = xw->pkg;
	const struct tb_xdomain_header *xhdr = &pkg->xd_hdr;
	size_t pkg_len = xw->pkg_len;
	struct tb *tb = xw->tb;
	struct tb_ctl *ctl = tb->ctl;
	struct tb_xdomain *xd;
	const uuid_t *uuid;
	int ret = 0;
	u32 sequence;
	u64 route;

	route = ((u64)xhdr->route_hi << 32 | xhdr->route_lo) & ~BIT_ULL(63);
	sequence = xhdr->length_sn & TB_XDOMAIN_SN_MASK;
	sequence >>= TB_XDOMAIN_SN_SHIFT;

	mutex_lock(&tb->lock);
	if (tb->root_switch)
		uuid = tb->root_switch->uuid;
	else
		uuid = NULL;
	mutex_unlock(&tb->lock);

	if (!uuid) {
		tb_xdp_error_response(ctl, route, sequence, ERROR_NOT_READY);
		goto out;
	}

	xd = tb_xdomain_find_by_route_locked(tb, route);
	if (xd)
		update_property_block(xd);

	switch (pkg->type) {
	case PROPERTIES_REQUEST:
		tb_dbg(tb, "%llx: received XDomain properties request\n", route);
		if (xd && pkg_len >= sizeof(struct tb_xdp_properties)) {
			ret = tb_xdp_properties_response(tb, ctl, xd, sequence,
				(const struct tb_xdp_properties *)pkg);
		}
		break;

	case PROPERTIES_CHANGED_REQUEST:
		tb_dbg(tb, "%llx: received XDomain properties changed request\n",
		       route);

		ret = tb_xdp_properties_changed_response(ctl, route, sequence);

		/*
		 * Since the properties have been changed, let's update
		 * the xdomain related to this connection as well in
		 * case there is a change in services it offers.
		 */
		if (xd) {
			mutex_lock(&xd->lock);
			if (!xd->removing && device_is_registered(&xd->dev))
				queue_delayed_work(tb->wq, &xd->state_work,
						   msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT));
			mutex_unlock(&xd->lock);
		}
		break;

	case UUID_REQUEST_OLD:
	case UUID_REQUEST:
		tb_dbg(tb, "%llx: received XDomain UUID request\n", route);
		ret = tb_xdp_uuid_response(ctl, route, sequence, uuid);
		/*
		 * If we've stopped the discovery with an error such as
		 * timing out, we will restart the handshake now that we
		 * received UUID request from the remote host.
		 */
		if (!ret && xd && xd->state == XDOMAIN_STATE_ERROR) {
			mutex_lock(&xd->lock);
			if (!xd->removing) {
				dev_dbg(&xd->dev, "restarting handshake\n");
				start_handshake(xd);
			}
			mutex_unlock(&xd->lock);
		}
		break;

	case LINK_STATE_STATUS_REQUEST:
		tb_dbg(tb, "%llx: received XDomain link state status request\n",
		       route);

		if (xd) {
			ret = tb_xdp_link_state_status_response(tb, ctl, xd,
								sequence);
		} else {
			tb_xdp_error_response(ctl, route, sequence,
					      ERROR_NOT_READY);
		}
		break;

	case LINK_STATE_CHANGE_REQUEST:
		tb_dbg(tb, "%llx: received XDomain link state change request\n",
		       route);

		if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH &&
		    pkg_len >= sizeof(struct tb_xdp_link_state_change)) {
			const struct tb_xdp_link_state_change *lsc =
				(const struct tb_xdp_link_state_change *)pkg;

			ret = tb_xdp_link_state_change_response(ctl, route,
								sequence, 0);
			mutex_lock(&xd->lock);
			if (!xd->removing) {
				xd->target_link_width = lsc->tlw;
				queue_delayed_work(tb->wq, &xd->state_work,
						   msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT));
			}
			mutex_unlock(&xd->lock);
		} else {
			tb_xdp_error_response(ctl, route, sequence,
					      ERROR_NOT_READY);
		}
		break;

	default:
		tb_dbg(tb, "%llx: unknown XDomain request %#x\n", route, pkg->type);
		tb_xdp_error_response(ctl, route, sequence,
				      ERROR_NOT_SUPPORTED);
		break;
	}

	tb_xdomain_put(xd);

	if (ret) {
		tb_warn(tb, "failed to send XDomain response for %#x\n",
			pkg->type);
	}

out:
	kfree(xw->pkg);
	kfree(xw);

	tb_domain_put(tb);
}

static bool
tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr,
			size_t size)
{
	struct xdomain_request_work *xw;

	xw = kmalloc_obj(*xw);
	if (!xw)
		return false;

	INIT_WORK(&xw->work, tb_xdp_handle_request);
	xw->pkg = kmemdup(hdr, size, GFP_KERNEL);
	if (!xw->pkg) {
		kfree(xw);
		return false;
	}
	xw->pkg_len = size;
	xw->tb = tb_domain_get(tb);

	schedule_work(&xw->work);
	return true;
}

/**
 * tb_register_service_driver() - Register XDomain service driver
 * @drv: Driver to register
 *
 * Registers new service driver from @drv to the bus.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_register_service_driver(struct tb_service_driver *drv)
{
	drv->driver.bus = &tb_bus_type;
	return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(tb_register_service_driver);

/**
 * tb_unregister_service_driver() - Unregister XDomain service driver
 * @drv: Driver to unregister
 *
 * Unregisters XDomain service driver from the bus.
 */
void tb_unregister_service_driver(struct tb_service_driver *drv)
{
	driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(tb_unregister_service_driver);

static ssize_t key_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	/*
	 * It should be null terminated but anything else is pretty much
	 * allowed.
	 */
	return sysfs_emit(buf, "%*pE\n", (int)strlen(svc->key), svc->key);
}
static DEVICE_ATTR_RO(key);

static int get_modalias(const struct tb_service *svc, char *buf, size_t size)
{
	return snprintf(buf, size, "tbsvc:k%sp%08Xv%08Xr%08X", svc->key,
			svc->prtcid, svc->prtcvers, svc->prtcrevs);
}

static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	/* Full buffer size except new line and null termination */
	get_modalias(svc, buf, PAGE_SIZE - 2);
	return strlen(strcat(buf, "\n"));
}
static DEVICE_ATTR_RO(modalias);

static ssize_t prtcid_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sysfs_emit(buf, "%u\n", svc->prtcid);
}
static DEVICE_ATTR_RO(prtcid);

static ssize_t prtcvers_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sysfs_emit(buf, "%u\n", svc->prtcvers);
}
static DEVICE_ATTR_RO(prtcvers);

static ssize_t prtcrevs_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sysfs_emit(buf, "%u\n", svc->prtcrevs);
}
static DEVICE_ATTR_RO(prtcrevs);

static ssize_t prtcstns_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sysfs_emit(buf, "0x%08x\n", svc->prtcstns);
}
static DEVICE_ATTR_RO(prtcstns);

static struct attribute *tb_service_attrs[] = {
	&dev_attr_key.attr,
	&dev_attr_modalias.attr,
	&dev_attr_prtcid.attr,
	&dev_attr_prtcvers.attr,
	&dev_attr_prtcrevs.attr,
	&dev_attr_prtcstns.attr,
	NULL,
};

static const struct attribute_group tb_service_attr_group = {
	.attrs = tb_service_attrs,
};

static const struct attribute_group *tb_service_attr_groups[] = {
	&tb_service_attr_group,
	NULL,
};

static int tb_service_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	const struct tb_service *svc = container_of_const(dev, struct tb_service, dev);
	char modalias[64];

	get_modalias(svc, modalias, sizeof(modalias));
	return add_uevent_var(env, "MODALIAS=%s", modalias);
}

static void tb_service_release(struct device *dev)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);
	struct tb_xdomain *xd = tb_service_parent(svc);

	tb_service_debugfs_remove(svc);
	ida_free(&xd->service_ids, svc->id);
	kfree(svc->key);
	kfree(svc);
}

const struct device_type tb_service_type = {
	.name = "thunderbolt_service",
	.groups = tb_service_attr_groups,
	.uevent = tb_service_uevent,
	.release = tb_service_release,
};
EXPORT_SYMBOL_GPL(tb_service_type);

static int remove_missing_service(struct device *dev, void *data)
{
	struct tb_xdomain *xd = data;
	struct tb_service *svc;

	svc = tb_to_service(dev);
	if (!svc)
		return 0;

	if (!tb_property_find(xd->remote_properties, svc->key,
			      TB_PROPERTY_TYPE_DIRECTORY))
		device_unregister(dev);

	return 0;
}

static int find_service(struct device *dev, const void *data)
{
	const struct tb_property *p = data;
	struct tb_service *svc;

	svc = tb_to_service(dev);
	if (!svc)
		return 0;

	return !strcmp(svc->key, p->key);
}

static int populate_service(struct tb_service *svc,
			    struct tb_property *property)
{
	struct tb_property_dir *dir = property->value.dir;
	struct tb_property *p;

	/* Fill in standard properties */
	p = tb_property_find(dir, "prtcid", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcid = p->value.immediate;
	p = tb_property_find(dir, "prtcvers", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcvers = p->value.immediate;
	p = tb_property_find(dir, "prtcrevs", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcrevs = p->value.immediate;
	p = tb_property_find(dir, "prtcstns", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcstns = p->value.immediate;

	svc->key = kstrdup(property->key, GFP_KERNEL);
	if (!svc->key)
		return -ENOMEM;

	return 0;
}

static void enumerate_services(struct tb_xdomain *xd)
{
	struct tb_service *svc;
	struct tb_property *p;
	struct device *dev;
	int id;

	/*
	 * First remove all services that are not available anymore in
	 * the updated property block.
	 */
	device_for_each_child_reverse(&xd->dev, xd, remove_missing_service);

	/* Then re-enumerate properties creating new services as we go */
	tb_property_for_each(xd->remote_properties, p) {
		if (p->type != TB_PROPERTY_TYPE_DIRECTORY)
			continue;

		/* If the service exists already we are fine */
		dev = device_find_child(&xd->dev, p, find_service);
		if (dev) {
			put_device(dev);
			continue;
		}

		svc = kzalloc_obj(*svc);
		if (!svc)
			break;

		if (populate_service(svc, p)) {
			kfree(svc);
			break;
		}

		id = ida_alloc(&xd->service_ids, GFP_KERNEL);
		if (id < 0) {
			kfree(svc->key);
			kfree(svc);
			break;
		}
		svc->id = id;
		svc->dev.bus = &tb_bus_type;
		svc->dev.type = &tb_service_type;
		svc->dev.parent = &xd->dev;
		dev_set_name(&svc->dev, "%s.%d", dev_name(&xd->dev), svc->id);

		tb_service_debugfs_init(svc);

		if (device_register(&svc->dev)) {
			put_device(&svc->dev);
			break;
		}
	}
}

static int populate_properties(struct tb_xdomain *xd,
			       struct tb_property_dir *dir)
{
	const struct tb_property *p;

	/* Required properties */
	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_VALUE);
	if (!p)
		return -EINVAL;
	xd->device = p->value.immediate;

	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_VALUE);
	if (!p)
		return -EINVAL;
	xd->vendor = p->value.immediate;

	p = tb_property_find(dir, "maxhopid", TB_PROPERTY_TYPE_VALUE);
	/*
	 * USB4 inter-domain spec suggests using 15 as HopID if the
	 * other end does not announce it in a property. This is for
	 * TBT3 compatibility.
	 */
	xd->remote_max_hopid = p ? p->value.immediate : XDOMAIN_DEFAULT_MAX_HOPID;

	kfree(xd->device_name);
	xd->device_name = NULL;
	kfree(xd->vendor_name);
	xd->vendor_name = NULL;

	/* Optional properties */
	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_TEXT);
	if (p)
		xd->device_name = kstrdup(p->value.text, GFP_KERNEL);
	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_TEXT);
	if (p)
		xd->vendor_name = kstrdup(p->value.text, GFP_KERNEL);

	return 0;
}

static int tb_xdomain_update_link_attributes(struct tb_xdomain *xd)
{
	bool change = false;
	struct tb_port *port;
	int ret;

	port = tb_xdomain_downstream_port(xd);

	ret = tb_port_get_link_speed(port);
	if (ret < 0)
		return ret;

	if (xd->link_speed != ret)
		change = true;

	xd->link_speed = ret;

	ret = tb_port_get_link_width(port);
	if (ret < 0)
		return ret;

	if (xd->link_width != ret)
		change = true;

	xd->link_width = ret;

	if (change)
		kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE);

	return 0;
}

static int tb_xdomain_get_uuid(struct tb_xdomain *xd)
{
	struct tb *tb = xd->tb;
	uuid_t uuid;
	u64 route;
	int ret;

	dev_dbg(&xd->dev, "requesting remote UUID\n");

	ret = tb_xdp_uuid_request(tb->ctl, xd->route, xd->state_retries, &uuid,
				  &route);
	if (ret < 0) {
		if (xd->state_retries-- > 0) {
			dev_dbg(&xd->dev, "failed to request UUID, retrying\n");
			return -EAGAIN;
		}
		dev_dbg(&xd->dev, "failed to read remote UUID\n");
		return ret;
	}

	dev_dbg(&xd->dev, "got remote UUID %pUb\n", &uuid);

	if (uuid_equal(&uuid, xd->local_uuid)) {
		if (route == xd->route)
			dev_dbg(&xd->dev, "loop back detected\n");
		else
			dev_dbg(&xd->dev, "intra-domain loop detected\n");

		/* Don't bond lanes automatically for loops */
		xd->bonding_possible = false;
	}

	/*
	 * If the UUID is different, there is another domain connected
	 * so mark this one unplugged and wait for the connection
	 * manager to replace it.
	 */
	if (xd->remote_uuid && !uuid_equal(&uuid, xd->remote_uuid)) {
		dev_dbg(&xd->dev, "remote UUID is different, unplugging\n");
		xd->is_unplugged = true;
		return -ENODEV;
	}

	/* First time fill in the missing UUID */
	if (!xd->remote_uuid) {
		xd->remote_uuid = kmemdup(&uuid, sizeof(uuid_t), GFP_KERNEL);
		if (!xd->remote_uuid)
			return -ENOMEM;
	}

	return 0;
}

static int tb_xdomain_get_link_status(struct tb_xdomain *xd)
{
	struct tb *tb = xd->tb;
	u8 slw, tlw, sls, tls;
	int ret;

	dev_dbg(&xd->dev, "sending link state status request to %pUb\n",
		xd->remote_uuid);

	ret = tb_xdp_link_state_status_request(tb->ctl, xd->route,
					       xd->state_retries, &slw, &tlw, &sls,
					       &tls);
	if (ret) {
		if (ret != -EOPNOTSUPP && xd->state_retries-- > 0) {
			dev_dbg(&xd->dev,
				"failed to request remote link status, retrying\n");
			return -EAGAIN;
		}
		dev_dbg(&xd->dev, "failed to receive remote link status\n");
		return ret;
	}

	dev_dbg(&xd->dev, "remote link supports width %#x speed %#x\n", slw, sls);

	if (slw < LANE_ADP_CS_0_SUPPORTED_WIDTH_DUAL) {
		dev_dbg(&xd->dev, "remote adapter is single lane only\n");
		return -EOPNOTSUPP;
	}

	return 0;
}

static int tb_xdomain_link_state_change(struct tb_xdomain *xd,
					unsigned int width)
{
	struct tb_port *port = tb_xdomain_downstream_port(xd);
	struct tb *tb = xd->tb;
	u8 tlw, tls;
	u32 val;
	int ret;

	if (width == 2)
		tlw = LANE_ADP_CS_1_TARGET_WIDTH_DUAL;
	else if (width == 1)
		tlw = LANE_ADP_CS_1_TARGET_WIDTH_SINGLE;
	else
		return -EINVAL;

	/* Use the current target speed */
	ret = tb_port_read(port, &val, TB_CFG_PORT, port->cap_phy + LANE_ADP_CS_1, 1);
	if (ret)
		return ret;
	tls = val & LANE_ADP_CS_1_TARGET_SPEED_MASK;

	dev_dbg(&xd->dev, "sending link state change request with width %#x speed %#x\n",
		tlw, tls);

	ret = tb_xdp_link_state_change_request(tb->ctl, xd->route,
					       xd->state_retries, tlw, tls);
	if (ret) {
		if (ret != -EOPNOTSUPP && xd->state_retries-- > 0) {
			dev_dbg(&xd->dev,
				"failed to change remote link state, retrying\n");
			return -EAGAIN;
		}
		dev_err(&xd->dev, "failed request link state change, aborting\n");
		return ret;
	}

	dev_dbg(&xd->dev, "received link state change response\n");
	return 0;
}

static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd)
{
	unsigned int width, width_mask;
	struct tb_port *port;
	int ret;

	if (xd->target_link_width == LANE_ADP_CS_1_TARGET_WIDTH_SINGLE) {
		width = TB_LINK_WIDTH_SINGLE;
		width_mask = width;
	} else if (xd->target_link_width == LANE_ADP_CS_1_TARGET_WIDTH_DUAL) {
		width = TB_LINK_WIDTH_DUAL;
		width_mask = width | TB_LINK_WIDTH_ASYM_TX | TB_LINK_WIDTH_ASYM_RX;
	} else {
		if (xd->state_retries-- > 0) {
			dev_dbg(&xd->dev,
				"link state change request not received yet, retrying\n");
			return -EAGAIN;
		}
		dev_dbg(&xd->dev, "timeout waiting for link change request\n");
		return -ETIMEDOUT;
	}

	port = tb_xdomain_downstream_port(xd);

	/*
	 * We can't use tb_xdomain_lane_bonding_enable() here because it
	 * is the other side that initiates lane bonding. So here we
	 * just set the width to both lane adapters and wait for the
	 * link to transition bonded.
	 */
	ret = tb_port_set_link_width(port->dual_link_port, width);
	if (ret) {
		tb_port_warn(port->dual_link_port,
			     "failed to set link width to %d\n", width);
		return ret;
	}

	ret = tb_port_set_link_width(port, width);
	if (ret) {
		tb_port_warn(port, "failed to set link width to %d\n", width);
		return ret;
	}

	ret = tb_port_wait_for_link_width(port, width_mask,
					  XDOMAIN_BONDING_TIMEOUT);
	if (ret) {
		dev_warn(&xd->dev, "error waiting for link width to become %d\n",
			 width_mask);
		return ret;
	}

	port->bonded = width > TB_LINK_WIDTH_SINGLE;
	port->dual_link_port->bonded = width > TB_LINK_WIDTH_SINGLE;

	tb_port_update_credits(port);
	tb_xdomain_update_link_attributes(xd);

	dev_dbg(&xd->dev, "lane bonding %s\n", str_enabled_disabled(width == 2));
	return 0;
}

static int tb_xdomain_get_properties(struct tb_xdomain *xd)
{
	struct tb_property_dir *dir;
	struct tb *tb = xd->tb;
	bool update = false;
	u32 *block = NULL;
	u32 gen = 0;
	int ret;

	dev_dbg(&xd->dev, "requesting remote properties\n");

	ret = tb_xdp_properties_request(tb->ctl, xd->route, xd->local_uuid,
					xd->remote_uuid, xd->state_retries,
					&block, &gen);
	if (ret < 0) {
		if (xd->state_retries-- > 0) {
			dev_dbg(&xd->dev,
				"failed to request remote properties, retrying\n");
			return -EAGAIN;
		}
		/* Give up now */
		dev_err(&xd->dev, "failed read XDomain properties from %pUb\n",
			xd->remote_uuid);

		return ret;
	}

	mutex_lock(&xd->lock);

	/* Only accept newer generation properties */
	if (xd->remote_properties && gen <= xd->remote_property_block_gen) {
		ret = 0;
		goto err_free_block;
	}

	dir = tb_property_parse_dir(block, ret);
	if (!dir) {
		dev_err(&xd->dev, "failed to parse XDomain properties\n");
		ret = -ENOMEM;
		goto err_free_block;
	}

	ret = populate_properties(xd, dir);
	if (ret) {
		dev_err(&xd->dev, "missing XDomain properties in response\n");
		goto err_free_dir;
	}

	/* Release the existing one */
	if (xd->remote_properties) {
		tb_property_free_dir(xd->remote_properties);
		update = true;
	}

	xd->remote_properties = dir;
	xd->remote_property_block_gen = gen;

	tb_xdomain_update_link_attributes(xd);

	mutex_unlock(&xd->lock);

	kfree(block);

	/*
	 * Now the device should be ready enough so we can add it to the
	 * bus and let userspace know about it. If the device is already
	 * registered, we notify the userspace that it has changed.
	 */
	if (!update) {
		/*
		 * Now disable lane 1 if bonding was not enabled. Do
		 * this only if bonding was possible at the beginning
		 * (that is we are the connection manager and there are
		 * two lanes).
		 */
		if (xd->bonding_possible) {
			struct tb_port *port;

			port = tb_xdomain_downstream_port(xd);
			if (!port->bonded)
				tb_port_disable(port->dual_link_port);
		}

		dev_dbg(&xd->dev, "current link speed %u.0 Gb/s\n",
			xd->link_speed);
		dev_dbg(&xd->dev, "current link width %s\n",
			tb_width_name(xd->link_width));

		if (device_add(&xd->dev)) {
			dev_err(&xd->dev, "failed to add XDomain device\n");
			return -ENODEV;
		}
		dev_info(&xd->dev, "new host found, vendor=%#x device=%#x\n",
			 xd->vendor, xd->device);
		if (xd->vendor_name && xd->device_name)
			dev_info(&xd->dev, "%s %s\n", xd->vendor_name,
				 xd->device_name);

		tb_xdomain_debugfs_init(xd);
	} else {
		kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE);
	}

	enumerate_services(xd);
	return 0;

err_free_dir:
	tb_property_free_dir(dir);
err_free_block:
	kfree(block);
	mutex_unlock(&xd->lock);

	return ret;
}

static void tb_xdomain_queue_uuid(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_UUID;
	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT));
}

static void tb_xdomain_queue_link_status(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_LINK_STATUS;
	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_queue_link_status2(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_LINK_STATUS2;
	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_queue_bonding(struct tb_xdomain *xd)
{
	if (memcmp(xd->local_uuid, xd->remote_uuid, UUID_SIZE) > 0) {
		dev_dbg(&xd->dev, "we have higher UUID, other side bonds the lanes\n");
		xd->state = XDOMAIN_STATE_BONDING_UUID_HIGH;
	} else {
		dev_dbg(&xd->dev, "we have lower UUID, bonding lanes\n");
		xd->state = XDOMAIN_STATE_LINK_STATE_CHANGE;
	}

	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_queue_bonding_uuid_low(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_BONDING_UUID_LOW;
	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_queue_properties(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_PROPERTIES;
	xd->state_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_queue_properties_changed(struct tb_xdomain *xd)
{
	xd->properties_changed_retries = XDOMAIN_RETRIES;
	queue_delayed_work(xd->tb->wq, &xd->properties_changed_work,
			   msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT));
}

static void tb_xdomain_failed(struct tb_xdomain *xd)
{
	xd->state = XDOMAIN_STATE_ERROR;
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_state_work(struct work_struct *work)
{
	struct tb_xdomain *xd = container_of(work, typeof(*xd), state_work.work);
	int ret, state = xd->state;

	if (WARN_ON_ONCE(state < XDOMAIN_STATE_INIT ||
			 state > XDOMAIN_STATE_ERROR))
		return;

	dev_dbg(&xd->dev, "running state %s\n", state_names[state]);

	switch (state) {
	case XDOMAIN_STATE_INIT:
		if (xd->needs_uuid) {
			tb_xdomain_queue_uuid(xd);
		} else {
			tb_xdomain_queue_properties_changed(xd);
			tb_xdomain_queue_properties(xd);
		}
		break;

	case XDOMAIN_STATE_UUID:
		ret = tb_xdomain_get_uuid(xd);
		if (ret) {
			if (ret == -EAGAIN)
				goto retry_state;
			tb_xdomain_failed(xd);
		} else {
			tb_xdomain_queue_properties_changed(xd);
			if (xd->bonding_possible)
				tb_xdomain_queue_link_status(xd);
			else
				tb_xdomain_queue_properties(xd);
		}
		break;

	case XDOMAIN_STATE_LINK_STATUS:
		ret = tb_xdomain_get_link_status(xd);
		if (ret) {
			if (ret == -EAGAIN)
				goto retry_state;

			/*
			 * If any of the lane bonding states fail we skip
			 * bonding completely and try to continue from
			 * reading properties.
			 */
			tb_xdomain_queue_properties(xd);
		} else {
			tb_xdomain_queue_bonding(xd);
		}
		break;

	case XDOMAIN_STATE_LINK_STATE_CHANGE:
		ret = tb_xdomain_link_state_change(xd, 2);
		if (ret) {
			if (ret == -EAGAIN)
				goto retry_state;
			tb_xdomain_queue_properties(xd);
		} else {
			tb_xdomain_queue_link_status2(xd);
		}
		break;

	case XDOMAIN_STATE_LINK_STATUS2:
		ret = tb_xdomain_get_link_status(xd);
		if (ret) {
			if (ret == -EAGAIN)
				goto retry_state;
			tb_xdomain_queue_properties(xd);
		} else {
			tb_xdomain_queue_bonding_uuid_low(xd);
		}
		break;

	case XDOMAIN_STATE_BONDING_UUID_LOW:
		tb_xdomain_lane_bonding_enable(xd);
		tb_xdomain_queue_properties(xd);
		break;

	case XDOMAIN_STATE_BONDING_UUID_HIGH:
		if (tb_xdomain_bond_lanes_uuid_high(xd) == -EAGAIN)
			goto retry_state;
		tb_xdomain_queue_properties(xd);
		break;

	case XDOMAIN_STATE_PROPERTIES:
		ret = tb_xdomain_get_properties(xd);
		if (ret) {
			if (ret == -EAGAIN)
				goto retry_state;
			tb_xdomain_failed(xd);
		} else {
			xd->state = XDOMAIN_STATE_ENUMERATED;
		}
		break;

	case XDOMAIN_STATE_ENUMERATED:
		tb_xdomain_queue_properties(xd);
		break;

	case XDOMAIN_STATE_ERROR:
		dev_dbg(&xd->dev, "discovery failed, stopping handshake\n");
		__stop_handshake(xd);
		break;

	default:
		dev_warn(&xd->dev, "unexpected state %d\n", state);
		break;
	}

	return;

retry_state:
	queue_delayed_work(xd->tb->wq, &xd->state_work,
			   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
}

static void tb_xdomain_properties_changed(struct work_struct *work)
{
	struct tb_xdomain *xd = container_of(work, typeof(*xd),
					     properties_changed_work.work);
	int ret;

	dev_dbg(&xd->dev, "sending properties changed notification\n");

	ret = tb_xdp_properties_changed_request(xd->tb->ctl, xd->route,
				xd->properties_changed_retries, xd->local_uuid);
	if (ret) {
		if (xd->properties_changed_retries-- > 0) {
			dev_dbg(&xd->dev,
				"failed to send properties changed notification, retrying\n");
			queue_delayed_work(xd->tb->wq,
					   &xd->properties_changed_work,
					   msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT));
		}
		dev_err(&xd->dev, "failed to send properties changed notification\n");
		return;
	}

	xd->properties_changed_retries = XDOMAIN_RETRIES;
}

static ssize_t device_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sysfs_emit(buf, "%#x\n", xd->device);
}
static DEVICE_ATTR_RO(device);

static ssize_t
device_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	int ret;

	if (mutex_lock_interruptible(&xd->lock))
		return -ERESTARTSYS;
	ret = sysfs_emit(buf, "%s\n", xd->device_name ?: "");
	mutex_unlock(&xd->lock);

	return ret;
}
static DEVICE_ATTR_RO(device_name);

static ssize_t maxhopid_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sysfs_emit(buf, "%d\n", xd->remote_max_hopid);
}
static DEVICE_ATTR_RO(maxhopid);

static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sysfs_emit(buf, "%#x\n", xd->vendor);
}
static DEVICE_ATTR_RO(vendor);

static ssize_t
vendor_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	int ret;

	if (mutex_lock_interruptible(&xd->lock))
		return -ERESTARTSYS;
	ret = sysfs_emit(buf, "%s\n", xd->vendor_name ?: "");
	mutex_unlock(&xd->lock);

	return ret;
}
static DEVICE_ATTR_RO(vendor_name);

static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sysfs_emit(buf, "%pUb\n", xd->remote_uuid);
}
static DEVICE_ATTR_RO(unique_id);

static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sysfs_emit(buf, "%u.0 Gb/s\n", xd->link_speed);
}

static DEVICE_ATTR(rx_speed, 0444, speed_show, NULL);
static DEVICE_ATTR(tx_speed, 0444, speed_show, NULL);

static ssize_t rx_lanes_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	unsigned int width;

	switch (xd->link_width) {
	case TB_LINK_WIDTH_SINGLE:
	case TB_LINK_WIDTH_ASYM_TX:
		width = 1;
		break;
	case TB_LINK_WIDTH_DUAL:
		width = 2;
		break;
	case TB_LINK_WIDTH_ASYM_RX:
		width = 3;
		break;
	default:
		WARN_ON_ONCE(1);
		return -EINVAL;
	}

	return sysfs_emit(buf, "%u\n", width);
}
static DEVICE_ATTR(rx_lanes, 0444, rx_lanes_show, NULL);

static ssize_t tx_lanes_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	unsigned int width;

	switch (xd->link_width) {
	case TB_LINK_WIDTH_SINGLE:
	case TB_LINK_WIDTH_ASYM_RX:
		width = 1;
		break;
	case TB_LINK_WIDTH_DUAL:
		width = 2;
		break;
	case TB_LINK_WIDTH_ASYM_TX:
		width = 3;
		break;
	default:
		WARN_ON_ONCE(1);
		return -EINVAL;
	}

	return sysfs_emit(buf, "%u\n", width);
}
static DEVICE_ATTR(tx_lanes, 0444, tx_lanes_show, NULL);

static struct attribute *xdomain_attrs[] = {
	&dev_attr_device.attr,
	&dev_attr_device_name.attr,
	&dev_attr_maxhopid.attr,
	&dev_attr_rx_lanes.attr,
	&dev_attr_rx_speed.attr,
	&dev_attr_tx_lanes.attr,
	&dev_attr_tx_speed.attr,
	&dev_attr_unique_id.attr,
	&dev_attr_vendor.attr,
	&dev_attr_vendor_name.attr,
	NULL,
};

static const struct attribute_group xdomain_attr_group = {
	.attrs = xdomain_attrs,
};

static const struct attribute_group *xdomain_attr_groups[] = {
	&xdomain_attr_group,
	NULL,
};

static void tb_xdomain_release(struct device *dev)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	put_device(xd->dev.parent);

	kfree(xd->local_property_block);
	tb_property_free_dir(xd->remote_properties);
	ida_destroy(&xd->out_hopids);
	ida_destroy(&xd->in_hopids);
	ida_destroy(&xd->service_ids);

	kfree(xd->local_uuid);
	kfree(xd->remote_uuid);
	kfree(xd->device_name);
	kfree(xd->vendor_name);
	kfree(xd);
}

static int __maybe_unused tb_xdomain_suspend(struct device *dev)
{
	stop_handshake(tb_to_xdomain(dev));
	return 0;
}

static int __maybe_unused tb_xdomain_resume(struct device *dev)
{
	start_handshake(tb_to_xdomain(dev));
	return 0;
}

static const struct dev_pm_ops tb_xdomain_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(tb_xdomain_suspend, tb_xdomain_resume)
};

const struct device_type tb_xdomain_type = {
	.name = "thunderbolt_xdomain",
	.release = tb_xdomain_release,
	.pm = &tb_xdomain_pm_ops,
};
EXPORT_SYMBOL_GPL(tb_xdomain_type);

static void tb_xdomain_link_init(struct tb_xdomain *xd, struct tb_port *down)
{
	if (!down->dual_link_port)
		return;

	/*
	 * Gen 4 links come up already as bonded so only update the port
	 * structures here.
	 */
	if (tb_port_get_link_generation(down) >= 4) {
		down->bonded = true;
		down->dual_link_port->bonded = true;
	} else {
		xd->bonding_possible = true;
	}
}

static void tb_xdomain_link_exit(struct tb_xdomain *xd)
{
	struct tb_port *down = tb_xdomain_downstream_port(xd);

	if (!down->dual_link_port)
		return;

	if (tb_port_get_link_generation(down) >= 4) {
		down->bonded = false;
		down->dual_link_port->bonded = false;
	} else if (xd->link_width > TB_LINK_WIDTH_SINGLE) {
		/*
		 * Just return port structures back to way they were and
		 * update credits. No need to update userspace because
		 * the XDomain is removed soon anyway.
		 */
		tb_port_lane_bonding_disable(down);
		tb_port_update_credits(down);
	} else if (down->dual_link_port) {
		/*
		 * Re-enable the lane 1 adapter we disabled at the end
		 * of tb_xdomain_get_properties().
		 */
		tb_port_enable(down->dual_link_port);
	}
}

/**
 * tb_xdomain_alloc() - Allocate new XDomain object
 * @tb: Domain where the XDomain belongs
 * @parent: Parent device (the switch through which the other domain
 *	    is reached).
 * @route: Route string used to reach the other domain
 * @local_uuid: Our local domain UUID
 * @remote_uuid: UUID of the other domain (optional)
 *
 * Allocates new XDomain structure and returns pointer to that. The
 * object must be released by calling tb_xdomain_put().
 *
 * Return: Pointer to &struct tb_xdomain, %NULL in case of failure.
 */
struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
				    u64 route, const uuid_t *local_uuid,
				    const uuid_t *remote_uuid)
{
	struct tb_switch *parent_sw = tb_to_switch(parent);
	struct tb_xdomain *xd;
	struct tb_port *down;

	/* Make sure the downstream domain is accessible */
	down = tb_port_at(route, parent_sw);
	tb_port_unlock(down);

	xd = kzalloc_obj(*xd);
	if (!xd)
		return NULL;

	xd->tb = tb;
	xd->route = route;
	xd->local_max_hopid = down->config.max_in_hop_id;
	ida_init(&xd->service_ids);
	ida_init(&xd->in_hopids);
	ida_init(&xd->out_hopids);
	mutex_init(&xd->lock);
	INIT_DELAYED_WORK(&xd->state_work, tb_xdomain_state_work);
	INIT_DELAYED_WORK(&xd->properties_changed_work,
			  tb_xdomain_properties_changed);

	xd->local_uuid = kmemdup(local_uuid, sizeof(uuid_t), GFP_KERNEL);
	if (!xd->local_uuid)
		goto err_free;

	if (remote_uuid) {
		xd->remote_uuid = kmemdup(remote_uuid, sizeof(uuid_t),
					  GFP_KERNEL);
		if (!xd->remote_uuid)
			goto err_free_local_uuid;
	} else {
		xd->needs_uuid = true;

		tb_xdomain_link_init(xd, down);
	}

	device_initialize(&xd->dev);
	xd->dev.parent = get_device(parent);
	xd->dev.bus = &tb_bus_type;
	xd->dev.type = &tb_xdomain_type;
	xd->dev.groups = xdomain_attr_groups;
	dev_set_name(&xd->dev, "%u-%llx", tb->index, route);

	dev_dbg(&xd->dev, "local UUID %pUb\n", local_uuid);
	if (remote_uuid)
		dev_dbg(&xd->dev, "remote UUID %pUb\n", remote_uuid);

	/*
	 * This keeps the DMA powered on as long as we have active
	 * connection to another host.
	 */
	pm_runtime_set_active(&xd->dev);
	pm_runtime_get_noresume(&xd->dev);
	pm_runtime_enable(&xd->dev);

	return xd;

err_free_local_uuid:
	kfree(xd->local_uuid);
err_free:
	kfree(xd);

	return NULL;
}

/**
 * tb_xdomain_add() - Add XDomain to the bus
 * @xd: XDomain to add
 *
 * This function starts XDomain discovery protocol handshake and
 * eventually adds the XDomain to the bus. After calling this function
 * the caller needs to call tb_xdomain_remove() in order to remove and
 * release the object regardless whether the handshake succeeded or not.
 */
void tb_xdomain_add(struct tb_xdomain *xd)
{
	/* Start exchanging properties with the other host */
	start_handshake(xd);
}

static int unregister_service(struct device *dev, void *data)
{
	device_unregister(dev);
	return 0;
}

/**
 * tb_xdomain_remove() - Remove XDomain from the bus
 * @xd: XDomain to remove
 *
 * This will stop all ongoing configuration work and remove the XDomain
 * along with any services from the bus. When the last reference to @xd
 * is released the object will be released as well.
 */
void tb_xdomain_remove(struct tb_xdomain *xd)
{
	tb_xdomain_debugfs_remove(xd);

	mutex_lock(&xd->lock);
	xd->removing = true;
	mutex_unlock(&xd->lock);

	stop_handshake(xd);

	device_for_each_child_reverse(&xd->dev, xd, unregister_service);

	tb_xdomain_link_exit(xd);

	/*
	 * Undo runtime PM here explicitly because it is possible that
	 * the XDomain was never added to the bus and thus device_del()
	 * is not called for it (device_del() would handle this otherwise).
	 */
	pm_runtime_disable(&xd->dev);
	pm_runtime_put_noidle(&xd->dev);
	pm_runtime_set_suspended(&xd->dev);

	if (!device_is_registered(&xd->dev)) {
		put_device(&xd->dev);
	} else {
		dev_info(&xd->dev, "host disconnected\n");
		device_unregister(&xd->dev);
	}
}

/**
 * tb_xdomain_lane_bonding_enable() - Enable lane bonding on XDomain
 * @xd: XDomain connection
 *
 * Lane bonding is disabled by default for XDomains. This function tries
 * to enable bonding by first enabling the port and waiting for the CL0
 * state.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_xdomain_lane_bonding_enable(struct tb_xdomain *xd)
{
	unsigned int width_mask;
	struct tb_port *port;
	int ret;

	port = tb_xdomain_downstream_port(xd);
	if (!port->dual_link_port)
		return -ENODEV;

	ret = tb_port_enable(port->dual_link_port);
	if (ret)
		return ret;

	ret = tb_wait_for_port(port->dual_link_port, true);
	if (ret < 0)
		return ret;
	if (!ret)
		return -ENOTCONN;

	ret = tb_port_lane_bonding_enable(port);
	if (ret) {
		tb_port_warn(port, "failed to enable lane bonding\n");
		return ret;
	}

	/* Any of the widths are all bonded */
	width_mask = TB_LINK_WIDTH_DUAL | TB_LINK_WIDTH_ASYM_TX |
		     TB_LINK_WIDTH_ASYM_RX;

	ret = tb_port_wait_for_link_width(port, width_mask,
					  XDOMAIN_BONDING_TIMEOUT);
	if (ret) {
		tb_port_warn(port, "failed to enable lane bonding\n");
		return ret;
	}

	tb_port_update_credits(port);
	tb_xdomain_update_link_attributes(xd);

	dev_dbg(&xd->dev, "lane bonding enabled\n");
	return 0;
}
EXPORT_SYMBOL_GPL(tb_xdomain_lane_bonding_enable);

/**
 * tb_xdomain_lane_bonding_disable() - Disable lane bonding
 * @xd: XDomain connection
 *
 * Lane bonding is disabled by default for XDomains. If bonding has been
 * enabled, this function can be used to disable it.
 */
void tb_xdomain_lane_bonding_disable(struct tb_xdomain *xd)
{
	struct tb_port *port;

	port = tb_xdomain_downstream_port(xd);
	if (port->dual_link_port) {
		int ret;

		tb_port_lane_bonding_disable(port);
		ret = tb_port_wait_for_link_width(port, TB_LINK_WIDTH_SINGLE, 100);
		if (ret == -ETIMEDOUT)
			tb_port_warn(port, "timeout disabling lane bonding\n");
		tb_port_disable(port->dual_link_port);
		tb_port_update_credits(port);
		tb_xdomain_update_link_attributes(xd);

		dev_dbg(&xd->dev, "lane bonding disabled\n");
	}
}
EXPORT_SYMBOL_GPL(tb_xdomain_lane_bonding_disable);

/**
 * tb_xdomain_alloc_in_hopid() - Allocate input HopID for tunneling
 * @xd: XDomain connection
 * @hopid: Preferred HopID or %-1 for next available
 *
 * Returned HopID is guaranteed to be within range supported by the input
 * lane adapter.
 * Call tb_xdomain_release_in_hopid() to release the allocated HopID.
 *
 * Return:
 * * Allocated HopID - On success.
 * * %-ENOSPC - If there are no more available HopIDs.
 * * Negative errno - Another error occurred.
 */
int tb_xdomain_alloc_in_hopid(struct tb_xdomain *xd, int hopid)
{
	if (hopid < 0)
		hopid = TB_PATH_MIN_HOPID;
	if (hopid < TB_PATH_MIN_HOPID || hopid > xd->local_max_hopid)
		return -EINVAL;

	return ida_alloc_range(&xd->in_hopids, hopid, xd->local_max_hopid,
			       GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(tb_xdomain_alloc_in_hopid);

/**
 * tb_xdomain_alloc_out_hopid() - Allocate output HopID for tunneling
 * @xd: XDomain connection
 * @hopid: Preferred HopID or %-1 for next available
 *
 * Returned HopID is guaranteed to be within range supported by the
 * output lane adapter.
 * Call tb_xdomain_release_out_hopid() to release the allocated HopID.
 *
 * Return:
 * * Allocated HopID - On success.
 * * %-ENOSPC - If there are no more available HopIDs.
 * * Negative errno - Another error occurred.
 */
int tb_xdomain_alloc_out_hopid(struct tb_xdomain *xd, int hopid)
{
	if (hopid < 0)
		hopid = TB_PATH_MIN_HOPID;
	if (hopid < TB_PATH_MIN_HOPID || hopid > xd->remote_max_hopid)
		return -EINVAL;

	return ida_alloc_range(&xd->out_hopids, hopid, xd->remote_max_hopid,
			       GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(tb_xdomain_alloc_out_hopid);

/**
 * tb_xdomain_release_in_hopid() - Release input HopID
 * @xd: XDomain connection
 * @hopid: HopID to release
 */
void tb_xdomain_release_in_hopid(struct tb_xdomain *xd, int hopid)
{
	ida_free(&xd->in_hopids, hopid);
}
EXPORT_SYMBOL_GPL(tb_xdomain_release_in_hopid);

/**
 * tb_xdomain_release_out_hopid() - Release output HopID
 * @xd: XDomain connection
 * @hopid: HopID to release
 */
void tb_xdomain_release_out_hopid(struct tb_xdomain *xd, int hopid)
{
	ida_free(&xd->out_hopids, hopid);
}
EXPORT_SYMBOL_GPL(tb_xdomain_release_out_hopid);

/**
 * tb_xdomain_enable_paths() - Enable DMA paths for XDomain connection
 * @xd: XDomain connection
 * @transmit_path: HopID we are using to send out packets
 * @transmit_ring: DMA ring used to send out packets
 * @receive_path: HopID the other end is using to send packets to us
 * @receive_ring: DMA ring used to receive packets from @receive_path
 *
 * The function enables DMA paths accordingly so that after successful
 * return the caller can send and receive packets using high-speed DMA
 * path. If a transmit or receive path is not needed, pass %-1 for those
 * parameters.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_xdomain_enable_paths(struct tb_xdomain *xd, int transmit_path,
			    int transmit_ring, int receive_path,
			    int receive_ring)
{
	return tb_domain_approve_xdomain_paths(xd->tb, xd, transmit_path,
					       transmit_ring, receive_path,
					       receive_ring);
}
EXPORT_SYMBOL_GPL(tb_xdomain_enable_paths);

/**
 * tb_xdomain_disable_paths() - Disable DMA paths for XDomain connection
 * @xd: XDomain connection
 * @transmit_path: HopID we are using to send out packets
 * @transmit_ring: DMA ring used to send out packets
 * @receive_path: HopID the other end is using to send packets to us
 * @receive_ring: DMA ring used to receive packets from @receive_path
 *
 * This does the opposite of tb_xdomain_enable_paths(). After call to
 * this the caller is not expected to use the rings anymore. Passing %-1
 * as path/ring parameter means don't care. Normally the callers should
 * pass the same values here as they do when paths are enabled.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_xdomain_disable_paths(struct tb_xdomain *xd, int transmit_path,
			     int transmit_ring, int receive_path,
			     int receive_ring)
{
	return tb_domain_disconnect_xdomain_paths(xd->tb, xd, transmit_path,
						  transmit_ring, receive_path,
						  receive_ring);
}
EXPORT_SYMBOL_GPL(tb_xdomain_disable_paths);

struct tb_xdomain_lookup {
	const uuid_t *uuid;
	u8 link;
	u8 depth;
	u64 route;
};

static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,
	const struct tb_xdomain_lookup *lookup)
{
	struct tb_port *port;

	tb_switch_for_each_port(sw, port) {
		struct tb_xdomain *xd;

		if (port->xdomain) {
			xd = port->xdomain;

			if (lookup->uuid) {
				if (xd->remote_uuid &&
				    uuid_equal(xd->remote_uuid, lookup->uuid))
					return xd;
			} else {
				if (lookup->link && lookup->link == xd->link &&
				    lookup->depth == xd->depth)
					return xd;
				if (lookup->route && lookup->route == xd->route)
					return xd;
			}
		} else if (tb_port_has_remote(port)) {
			xd = switch_find_xdomain(port->remote->sw, lookup);
			if (xd)
				return xd;
		}
	}

	return NULL;
}

/**
 * tb_xdomain_find_by_uuid() - Find an XDomain by UUID
 * @tb: Domain where the XDomain belongs to
 * @uuid: UUID to look for
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 *
 * Return: Pointer to &struct tb_xdomain or %NULL if not found.
 */
struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.uuid = uuid;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}
EXPORT_SYMBOL_GPL(tb_xdomain_find_by_uuid);

/**
 * tb_xdomain_find_by_link_depth() - Find an XDomain by link and depth
 * @tb: Domain where the XDomain belongs to
 * @link: Root switch link number
 * @depth: Depth in the link
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 *
 * Return: Pointer to &struct tb_xdomain or %NULL if not found.
 */
struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
						 u8 depth)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.link = link;
	lookup.depth = depth;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}

/**
 * tb_xdomain_find_by_route() - Find an XDomain by route string
 * @tb: Domain where the XDomain belongs to
 * @route: XDomain route string
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 *
 * Return: Pointer to &struct tb_xdomain or %NULL if not found.
 */
struct tb_xdomain *tb_xdomain_find_by_route(struct tb *tb, u64 route)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.route = route;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}
EXPORT_SYMBOL_GPL(tb_xdomain_find_by_route);

bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,
			       const void *buf, size_t size)
{
	const struct tb_protocol_handler *handler, *tmp;
	const struct tb_xdp_header *hdr = buf;
	unsigned int length;
	int ret = 0;

	/* We expect the packet is at least size of the header */
	length = hdr->xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK;
	if (length != size / 4 - sizeof(hdr->xd_hdr) / 4)
		return true;
	if (length < sizeof(*hdr) / 4 - sizeof(hdr->xd_hdr) / 4)
		return true;

	/*
	 * Handle XDomain discovery protocol packets directly here. For
	 * other protocols (based on their UUID) we call registered
	 * handlers in turn.
	 */
	if (uuid_equal(&hdr->uuid, &tb_xdp_uuid)) {
		if (type == TB_CFG_PKG_XDOMAIN_REQ)
			return tb_xdp_schedule_request(tb, hdr, size);
		return false;
	}

	mutex_lock(&xdomain_lock);
	list_for_each_entry_safe(handler, tmp, &protocol_handlers, list) {
		if (!uuid_equal(&hdr->uuid, handler->uuid))
			continue;

		mutex_unlock(&xdomain_lock);
		ret = handler->callback(buf, size, handler->data);
		mutex_lock(&xdomain_lock);

		if (ret)
			break;
	}
	mutex_unlock(&xdomain_lock);

	return ret > 0;
}

static int update_xdomain(struct device *dev, void *data)
{
	struct tb_xdomain *xd;

	xd = tb_to_xdomain(dev);
	if (xd) {
		mutex_lock(&xd->lock);
		if (!xd->removing)
			queue_delayed_work(xd->tb->wq,
					   &xd->properties_changed_work,
					   msecs_to_jiffies(50));
		mutex_unlock(&xd->lock);
	}

	return 0;
}

static void update_all_xdomains(void)
{
	bus_for_each_dev(&tb_bus_type, NULL, NULL, update_xdomain);
}

static bool remove_directory(const char *key, const struct tb_property_dir *dir)
{
	struct tb_property *p;

	p = tb_property_find(xdomain_property_dir, key,
			     TB_PROPERTY_TYPE_DIRECTORY);
	if (p && p->value.dir == dir) {
		tb_property_remove(p);
		return true;
	}
	return false;
}

/**
 * tb_register_property_dir() - Register property directory to the host
 * @key: Key (name) of the directory to add
 * @dir: Directory to add
 *
 * Service drivers can use this function to add new property directory
 * to the host available properties. The other connected hosts are
 * notified so they can re-read properties of this host if they are
 * interested.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_register_property_dir(const char *key, struct tb_property_dir *dir)
{
	int ret;

	if (WARN_ON(!xdomain_property_dir))
		return -EAGAIN;

	if (!key || strlen(key) > 8)
		return -EINVAL;

	mutex_lock(&xdomain_lock);
	if (tb_property_find(xdomain_property_dir, key,
			     TB_PROPERTY_TYPE_DIRECTORY)) {
		ret = -EEXIST;
		goto err_unlock;
	}

	ret = tb_property_add_dir(xdomain_property_dir, key, dir);
	if (ret)
		goto err_unlock;

	xdomain_property_block_gen++;

	mutex_unlock(&xdomain_lock);
	update_all_xdomains();
	return 0;

err_unlock:
	mutex_unlock(&xdomain_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(tb_register_property_dir);

/**
 * tb_unregister_property_dir() - Removes property directory from host
 * @key: Key (name) of the directory
 * @dir: Directory to remove
 *
 * This will remove the existing directory from this host and notify the
 * connected hosts about the change.
 */
void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir)
{
	int ret = 0;

	mutex_lock(&xdomain_lock);
	if (remove_directory(key, dir))
		xdomain_property_block_gen++;
	mutex_unlock(&xdomain_lock);

	if (!ret)
		update_all_xdomains();
}
EXPORT_SYMBOL_GPL(tb_unregister_property_dir);

int tb_xdomain_init(void)
{
	xdomain_property_dir = tb_property_create_dir(NULL);
	if (!xdomain_property_dir)
		return -ENOMEM;

	/*
	 * Initialize standard set of properties without any service
	 * directories. Those will be added by service drivers
	 * themselves when they are loaded.
	 *
	 * Rest of the properties are filled dynamically based on these
	 * when the P2P connection is made.
	 */
	tb_property_add_immediate(xdomain_property_dir, "vendorid", 0x1d6b);
	tb_property_add_text(xdomain_property_dir, "vendorid", "Linux");
	tb_property_add_immediate(xdomain_property_dir, "deviceid", 0x0004);
	tb_property_add_immediate(xdomain_property_dir, "devicerv", 0x80000100);

	xdomain_property_block_gen = get_random_u32();
	return 0;
}

void tb_xdomain_exit(void)
{
	tb_property_free_dir(xdomain_property_dir);
}
