/*
 * Thunderbolt DMA configuration based mailbox support
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/slab.h>

#include "dma_port.h"
#include "tb_regs.h"

#define DMA_PORT_CAP			0x3e

#define MAIL_DATA			1
#define MAIL_DATA_DWORDS		16

#define MAIL_IN				17
#define MAIL_IN_CMD_SHIFT		28
#define MAIL_IN_CMD_MASK		GENMASK(31, 28)
#define MAIL_IN_CMD_FLASH_WRITE		0x0
#define MAIL_IN_CMD_FLASH_UPDATE_AUTH	0x1
#define MAIL_IN_CMD_FLASH_READ		0x2
#define MAIL_IN_CMD_POWER_CYCLE		0x4
#define MAIL_IN_DWORDS_SHIFT		24
#define MAIL_IN_DWORDS_MASK		GENMASK(27, 24)
#define MAIL_IN_ADDRESS_SHIFT		2
#define MAIL_IN_ADDRESS_MASK		GENMASK(23, 2)
#define MAIL_IN_CSS			BIT(1)
#define MAIL_IN_OP_REQUEST		BIT(0)

#define MAIL_OUT			18
#define MAIL_OUT_STATUS_RESPONSE	BIT(29)
#define MAIL_OUT_STATUS_CMD_SHIFT	4
#define MAIL_OUT_STATUS_CMD_MASK	GENMASK(7, 4)
#define MAIL_OUT_STATUS_MASK		GENMASK(3, 0)
#define MAIL_OUT_STATUS_COMPLETED	0
#define MAIL_OUT_STATUS_ERR_AUTH	1
#define MAIL_OUT_STATUS_ERR_ACCESS	2

#define DMA_PORT_TIMEOUT		5000 /* ms */
#define DMA_PORT_RETRIES		3

/**
 * struct tb_dma_port - DMA control port
 * @sw: Switch the DMA port belongs to
 * @port: Switch port number where DMA capability is found
 * @base: Start offset of the mailbox registers
 * @buf: Temporary buffer to store a single block
 */
struct tb_dma_port {
	struct tb_switch *sw;
	u8 port;
	u32 base;
	u8 *buf;
};

/*
 * When the switch is in safe mode it supports very little functionality
 * so we don't validate that much here.
 */
static bool dma_port_match(const struct tb_cfg_request *req,
			   const struct ctl_pkg *pkg)
{
	u64 route = tb_cfg_get_route(pkg->buffer) & ~BIT_ULL(63);

	if (pkg->frame.eof == TB_CFG_PKG_ERROR)
		return true;
	if (pkg->frame.eof != req->response_type)
		return false;
	if (route != tb_cfg_get_route(req->request))
		return false;
	if (pkg->frame.size != req->response_size)
		return false;

	return true;
}

static bool dma_port_copy(struct tb_cfg_request *req, const struct ctl_pkg *pkg)
{
	memcpy(req->response, pkg->buffer, req->response_size);
	return true;
}

static int dma_port_read(struct tb_ctl *ctl, void *buffer, u64 route,
			 u32 port, u32 offset, u32 length, int timeout_msec)
{
	struct cfg_read_pkg request = {
		.header = tb_cfg_make_header(route),
		.addr = {
			.seq = 1,
			.port = port,
			.space = TB_CFG_PORT,
			.offset = offset,
			.length = length,
		},
	};
	struct tb_cfg_request *req;
	struct cfg_write_pkg reply;
	struct tb_cfg_result res;

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

	req->match = dma_port_match;
	req->copy = dma_port_copy;
	req->request = &request;
	req->request_size = sizeof(request);
	req->request_type = TB_CFG_PKG_READ;
	req->response = &reply;
	req->response_size = 12 + 4 * length;
	req->response_type = TB_CFG_PKG_READ;

	res = tb_cfg_request_sync(ctl, req, timeout_msec);

	tb_cfg_request_put(req);

	if (res.err)
		return res.err;

	memcpy(buffer, &reply.data, 4 * length);
	return 0;
}

static int dma_port_write(struct tb_ctl *ctl, const void *buffer, u64 route,
			  u32 port, u32 offset, u32 length, int timeout_msec)
{
	struct cfg_write_pkg request = {
		.header = tb_cfg_make_header(route),
		.addr = {
			.seq = 1,
			.port = port,
			.space = TB_CFG_PORT,
			.offset = offset,
			.length = length,
		},
	};
	struct tb_cfg_request *req;
	struct cfg_read_pkg reply;
	struct tb_cfg_result res;

	memcpy(&request.data, buffer, length * 4);

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

	req->match = dma_port_match;
	req->copy = dma_port_copy;
	req->request = &request;
	req->request_size = 12 + 4 * length;
	req->request_type = TB_CFG_PKG_WRITE;
	req->response = &reply;
	req->response_size = sizeof(reply);
	req->response_type = TB_CFG_PKG_WRITE;

	res = tb_cfg_request_sync(ctl, req, timeout_msec);

	tb_cfg_request_put(req);

	return res.err;
}

static int dma_find_port(struct tb_switch *sw)
{
	int port, ret;
	u32 type;

	/*
	 * The DMA (NHI) port is either 3 or 5 depending on the
	 * controller. Try both starting from 5 which is more common.
	 */
	port = 5;
	ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1,
			    DMA_PORT_TIMEOUT);
	if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
		return port;

	port = 3;
	ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1,
			    DMA_PORT_TIMEOUT);
	if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
		return port;

	return -ENODEV;
}

/**
 * dma_port_alloc() - Finds DMA control port from a switch pointed by route
 * @sw: Switch from where find the DMA port
 *
 * Function checks if the switch NHI port supports DMA configuration
 * based mailbox capability and if it does, allocates and initializes
 * DMA port structure. Returns %NULL if the capabity was not found.
 *
 * The DMA control port is functional also when the switch is in safe
 * mode.
 */
struct tb_dma_port *dma_port_alloc(struct tb_switch *sw)
{
	struct tb_dma_port *dma;
	int port;

	port = dma_find_port(sw);
	if (port < 0)
		return NULL;

	dma = kzalloc(sizeof(*dma), GFP_KERNEL);
	if (!dma)
		return NULL;

	dma->buf = kmalloc_array(MAIL_DATA_DWORDS, sizeof(u32), GFP_KERNEL);
	if (!dma->buf) {
		kfree(dma);
		return NULL;
	}

	dma->sw = sw;
	dma->port = port;
	dma->base = DMA_PORT_CAP;

	return dma;
}

/**
 * dma_port_free() - Release DMA control port structure
 * @dma: DMA control port
 */
void dma_port_free(struct tb_dma_port *dma)
{
	if (dma) {
		kfree(dma->buf);
		kfree(dma);
	}
}

static int dma_port_wait_for_completion(struct tb_dma_port *dma,
					unsigned int timeout)
{
	unsigned long end = jiffies + msecs_to_jiffies(timeout);
	struct tb_switch *sw = dma->sw;

	do {
		int ret;
		u32 in;

		ret = dma_port_read(sw->tb->ctl, &in, tb_route(sw), dma->port,
				    dma->base + MAIL_IN, 1, 50);
		if (ret) {
			if (ret != -ETIMEDOUT)
				return ret;
		} else if (!(in & MAIL_IN_OP_REQUEST)) {
			return 0;
		}

		usleep_range(50, 100);
	} while (time_before(jiffies, end));

	return -ETIMEDOUT;
}

static int status_to_errno(u32 status)
{
	switch (status & MAIL_OUT_STATUS_MASK) {
	case MAIL_OUT_STATUS_COMPLETED:
		return 0;
	case MAIL_OUT_STATUS_ERR_AUTH:
		return -EINVAL;
	case MAIL_OUT_STATUS_ERR_ACCESS:
		return -EACCES;
	}

	return -EIO;
}

static int dma_port_request(struct tb_dma_port *dma, u32 in,
			    unsigned int timeout)
{
	struct tb_switch *sw = dma->sw;
	u32 out;
	int ret;

	ret = dma_port_write(sw->tb->ctl, &in, tb_route(sw), dma->port,
			     dma->base + MAIL_IN, 1, DMA_PORT_TIMEOUT);
	if (ret)
		return ret;

	ret = dma_port_wait_for_completion(dma, timeout);
	if (ret)
		return ret;

	ret = dma_port_read(sw->tb->ctl, &out, tb_route(sw), dma->port,
			    dma->base + MAIL_OUT, 1, DMA_PORT_TIMEOUT);
	if (ret)
		return ret;

	return status_to_errno(out);
}

static int dma_port_flash_read_block(struct tb_dma_port *dma, u32 address,
				     void *buf, u32 size)
{
	struct tb_switch *sw = dma->sw;
	u32 in, dwaddress, dwords;
	int ret;

	dwaddress = address / 4;
	dwords = size / 4;

	in = MAIL_IN_CMD_FLASH_READ << MAIL_IN_CMD_SHIFT;
	if (dwords < MAIL_DATA_DWORDS)
		in |= (dwords << MAIL_IN_DWORDS_SHIFT) & MAIL_IN_DWORDS_MASK;
	in |= (dwaddress << MAIL_IN_ADDRESS_SHIFT) & MAIL_IN_ADDRESS_MASK;
	in |= MAIL_IN_OP_REQUEST;

	ret = dma_port_request(dma, in, DMA_PORT_TIMEOUT);
	if (ret)
		return ret;

	return dma_port_read(sw->tb->ctl, buf, tb_route(sw), dma->port,
			     dma->base + MAIL_DATA, dwords, DMA_PORT_TIMEOUT);
}

static int dma_port_flash_write_block(struct tb_dma_port *dma, u32 address,
				      const void *buf, u32 size)
{
	struct tb_switch *sw = dma->sw;
	u32 in, dwaddress, dwords;
	int ret;

	dwords = size / 4;

	/* Write the block to MAIL_DATA registers */
	ret = dma_port_write(sw->tb->ctl, buf, tb_route(sw), dma->port,
			    dma->base + MAIL_DATA, dwords, DMA_PORT_TIMEOUT);

	in = MAIL_IN_CMD_FLASH_WRITE << MAIL_IN_CMD_SHIFT;

	/* CSS header write is always done to the same magic address */
	if (address >= DMA_PORT_CSS_ADDRESS) {
		dwaddress = DMA_PORT_CSS_ADDRESS;
		in |= MAIL_IN_CSS;
	} else {
		dwaddress = address / 4;
	}

	in |= ((dwords - 1) << MAIL_IN_DWORDS_SHIFT) & MAIL_IN_DWORDS_MASK;
	in |= (dwaddress << MAIL_IN_ADDRESS_SHIFT) & MAIL_IN_ADDRESS_MASK;
	in |= MAIL_IN_OP_REQUEST;

	return dma_port_request(dma, in, DMA_PORT_TIMEOUT);
}

/**
 * dma_port_flash_read() - Read from active flash region
 * @dma: DMA control port
 * @address: Address relative to the start of active region
 * @buf: Buffer where the data is read
 * @size: Size of the buffer
 */
int dma_port_flash_read(struct tb_dma_port *dma, unsigned int address,
			void *buf, size_t size)
{
	unsigned int retries = DMA_PORT_RETRIES;
	unsigned int offset;

	offset = address & 3;
	address = address & ~3;

	do {
		u32 nbytes = min_t(u32, size, MAIL_DATA_DWORDS * 4);
		int ret;

		ret = dma_port_flash_read_block(dma, address, dma->buf,
						ALIGN(nbytes, 4));
		if (ret) {
			if (ret == -ETIMEDOUT) {
				if (retries--)
					continue;
				ret = -EIO;
			}
			return ret;
		}

		memcpy(buf, dma->buf + offset, nbytes);

		size -= nbytes;
		address += nbytes;
		buf += nbytes;
	} while (size > 0);

	return 0;
}

/**
 * dma_port_flash_write() - Write to non-active flash region
 * @dma: DMA control port
 * @address: Address relative to the start of non-active region
 * @buf: Data to write
 * @size: Size of the buffer
 *
 * Writes block of data to the non-active flash region of the switch. If
 * the address is given as %DMA_PORT_CSS_ADDRESS the block is written
 * using CSS command.
 */
int dma_port_flash_write(struct tb_dma_port *dma, unsigned int address,
			 const void *buf, size_t size)
{
	unsigned int retries = DMA_PORT_RETRIES;
	unsigned int offset;

	if (address >= DMA_PORT_CSS_ADDRESS) {
		offset = 0;
		if (size > DMA_PORT_CSS_MAX_SIZE)
			return -E2BIG;
	} else {
		offset = address & 3;
		address = address & ~3;
	}

	do {
		u32 nbytes = min_t(u32, size, MAIL_DATA_DWORDS * 4);
		int ret;

		memcpy(dma->buf + offset, buf, nbytes);

		ret = dma_port_flash_write_block(dma, address, buf, nbytes);
		if (ret) {
			if (ret == -ETIMEDOUT) {
				if (retries--)
					continue;
				ret = -EIO;
			}
			return ret;
		}

		size -= nbytes;
		address += nbytes;
		buf += nbytes;
	} while (size > 0);

	return 0;
}

/**
 * dma_port_flash_update_auth() - Starts flash authenticate cycle
 * @dma: DMA control port
 *
 * Starts the flash update authentication cycle. If the image in the
 * non-active area was valid, the switch starts upgrade process where
 * active and non-active area get swapped in the end. Caller should call
 * dma_port_flash_update_auth_status() to get status of this command.
 * This is because if the switch in question is root switch the
 * thunderbolt host controller gets reset as well.
 */
int dma_port_flash_update_auth(struct tb_dma_port *dma)
{
	u32 in;

	in = MAIL_IN_CMD_FLASH_UPDATE_AUTH << MAIL_IN_CMD_SHIFT;
	in |= MAIL_IN_OP_REQUEST;

	return dma_port_request(dma, in, 150);
}

/**
 * dma_port_flash_update_auth_status() - Reads status of update auth command
 * @dma: DMA control port
 * @status: Status code of the operation
 *
 * The function checks if there is status available from the last update
 * auth command. Returns %0 if there is no status and no further
 * action is required. If there is status, %1 is returned instead and
 * @status holds the failure code.
 *
 * Negative return means there was an error reading status from the
 * switch.
 */
int dma_port_flash_update_auth_status(struct tb_dma_port *dma, u32 *status)
{
	struct tb_switch *sw = dma->sw;
	u32 out, cmd;
	int ret;

	ret = dma_port_read(sw->tb->ctl, &out, tb_route(sw), dma->port,
			    dma->base + MAIL_OUT, 1, DMA_PORT_TIMEOUT);
	if (ret)
		return ret;

	/* Check if the status relates to flash update auth */
	cmd = (out & MAIL_OUT_STATUS_CMD_MASK) >> MAIL_OUT_STATUS_CMD_SHIFT;
	if (cmd == MAIL_IN_CMD_FLASH_UPDATE_AUTH) {
		if (status)
			*status = out & MAIL_OUT_STATUS_MASK;

		/* Reset is needed in any case */
		return 1;
	}

	return 0;
}

/**
 * dma_port_power_cycle() - Power cycles the switch
 * @dma: DMA control port
 *
 * Triggers power cycle to the switch.
 */
int dma_port_power_cycle(struct tb_dma_port *dma)
{
	u32 in;

	in = MAIL_IN_CMD_POWER_CYCLE << MAIL_IN_CMD_SHIFT;
	in |= MAIL_IN_OP_REQUEST;

	return dma_port_request(dma, in, 150);
}
