/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */

#include <assert.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/aspeed-lpc-ctrl.h>

#define pr_fmt(x) "astlpc: " x

#include "libmctp.h"
#include "libmctp-alloc.h"
#include "libmctp-log.h"
#include "libmctp-astlpc.h"

struct mctp_binding_astlpc {
	struct mctp_binding	binding;
	void			*lpc_map_base;
	union {
		void			*lpc_map;
		struct mctp_lpcmap_hdr	*lpc_hdr;
	};
	int			kcs_fd;
	uint8_t			kcs_status;

	bool			running;

	/* temporary transmit buffer */
	uint8_t			txbuf[256];
};

#ifndef container_of
#define container_of(ptr, type, member) \
    (type *)((char *)(ptr) - (char *)&((type *)0)->member)
#endif

#define binding_to_astlpc(b) \
	container_of(b, struct mctp_binding_astlpc, binding)

#define MCTP_MAGIC	0x4d435450
#define BMC_VER_MIN	1
#define BMC_VER_CUR	1

struct mctp_lpcmap_hdr {
	uint32_t	magic;

	uint16_t	bmc_ver_min;
	uint16_t	bmc_ver_cur;
	uint16_t	host_ver_min;
	uint16_t	host_ver_cur;
	uint16_t	negotiated_ver;
	uint16_t	pad0;

	uint32_t	rx_offset;
	uint32_t	rx_size;
	uint32_t	tx_offset;
	uint32_t	tx_size;
} __attribute__((packed));

/* layout of TX/RX areas */
static const uint32_t	rx_offset = 0x100;
static const uint32_t	rx_size   = 0x100;
static const uint32_t	tx_offset = 0x200;
static const uint32_t	tx_size   = 0x100;

/* kernel interface */
static const char *kcs_path = "/dev/mctp0";
static const char *lpc_path = "/dev/aspeed-lpc-ctrl";

#define LPC_WIN_SIZE                (1 * 1024 * 1024)

enum {
	KCS_REG_DATA = 0,
	KCS_REG_STATUS = 1,
};

#define KCS_STATUS_BMC_READY		0x80
#define KCS_STATUS_CHANNEL_ACTIVE	0x40
#define KCS_STATUS_IBF			0x02
#define KCS_STATUS_OBF			0x01

static int mctp_astlpc_kcs_set_status(struct mctp_binding_astlpc *astlpc,
		uint8_t status)
{
	int rc;

	rc = pwrite(astlpc->kcs_fd, &status, 1, KCS_REG_STATUS);
	if (rc != 1) {
		mctp_prwarn("KCS status write failed");
		return -1;
	}
	return 0;
}

static int mctp_astlpc_kcs_send(struct mctp_binding_astlpc *astlpc,
		uint8_t data)
{
	uint8_t status;
	int rc;

	for (;;) {
		rc = pread(astlpc->kcs_fd, &status, 1, KCS_REG_STATUS);
		if (rc != 1) {
			mctp_prwarn("KCE status read failed");
			return -1;
		}
		if (!(status & KCS_STATUS_OBF))
			break;
		/* todo: timeout */
	}

	rc = pwrite(astlpc->kcs_fd, &data, 1, KCS_REG_DATA);
	if (rc != 1) {
		mctp_prwarn("KCS data write failed");
		return -1;
	}

	return 0;
}

static int mctp_binding_astlpc_tx(struct mctp_binding *b,
		struct mctp_pktbuf *pkt)
{
	struct mctp_binding_astlpc *astlpc = binding_to_astlpc(b);
	uint32_t len;

	len = mctp_pktbuf_size(pkt);
	if (len > rx_size - 4) {
		mctp_prwarn("invalid TX len 0x%x", len);
		return -1;
	}

	*(uint32_t *)(astlpc->lpc_map + rx_offset) = htobe32(len);

	memcpy(astlpc->lpc_map + rx_offset + 4, mctp_pktbuf_hdr(pkt), len);

	mctp_binding_set_tx_enabled(b, false);

	mctp_astlpc_kcs_send(astlpc, 0x1);
	return 0;
}

static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
{
	/* todo: actual version negotiation */
	astlpc->lpc_hdr->negotiated_ver = htobe16(1);
	mctp_astlpc_kcs_set_status(astlpc,
			KCS_STATUS_BMC_READY | KCS_STATUS_CHANNEL_ACTIVE |
			KCS_STATUS_OBF);

	mctp_binding_set_tx_enabled(&astlpc->binding, true);
}

static void mctp_astlpc_rx_start(struct mctp_binding_astlpc *astlpc)
{
	struct mctp_pktbuf *pkt;
	uint32_t len;

	len = htobe32(*(uint32_t *)(astlpc->lpc_map + tx_offset));
	if (len > tx_size - 4) {
		mctp_prwarn("invalid RX len 0x%x", len);
		return;
	}

	if (len > MCTP_MTU + sizeof(struct mctp_hdr)) {
		mctp_prwarn("invalid RX len 0x%x", len);
		return;
	}

	pkt = mctp_pktbuf_alloc(len);
	if (!pkt)
		goto out_complete;

	memcpy(mctp_pktbuf_hdr(pkt), astlpc->lpc_map + tx_offset + 4, len);

	mctp_bus_rx(&astlpc->binding, pkt);

out_complete:
	mctp_astlpc_kcs_send(astlpc, 0x2);
}

static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
{
	mctp_binding_set_tx_enabled(&astlpc->binding, true);
}

int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc)
{
	uint8_t kcs_regs[2], data;
	int rc;

	rc = pread(astlpc->kcs_fd, kcs_regs, 2, 0);
	if (rc < 0) {
		mctp_prwarn("KCS read error");
		return -1;
	} else if (rc != 2) {
		mctp_prwarn("KCS short read (%d)", rc);
		return -1;
	}

	if (!(kcs_regs[KCS_REG_STATUS] & KCS_STATUS_IBF))
		return 0;

	data = kcs_regs[KCS_REG_DATA];
	switch (data) {
	case 0x0:
		mctp_astlpc_init_channel(astlpc);
		break;
	case 0x1:
		mctp_astlpc_rx_start(astlpc);
		break;
	case 0x2:
		mctp_astlpc_tx_complete(astlpc);
		break;
	default:
		mctp_prwarn("unknown message 0x%x", data);
	}
	return 0;
}

int mctp_astlpc_get_fd(struct mctp_binding_astlpc *astlpc)
{
	return astlpc->kcs_fd;
}


void mctp_astlpc_register_bus(struct mctp_binding_astlpc *astlpc,
		struct mctp *mctp, mctp_eid_t eid)
{
	mctp_register_bus(mctp, &astlpc->binding, eid);
}

static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
{
	uint8_t status;
	int rc;

	astlpc->lpc_hdr->magic = htobe32(MCTP_MAGIC);
	astlpc->lpc_hdr->bmc_ver_min = htobe16(BMC_VER_MIN);
	astlpc->lpc_hdr->bmc_ver_cur = htobe16(BMC_VER_CUR);

	astlpc->lpc_hdr->rx_offset = htobe32(rx_offset);
	astlpc->lpc_hdr->rx_size = htobe32(rx_size);
	astlpc->lpc_hdr->tx_offset = htobe32(tx_offset);
	astlpc->lpc_hdr->tx_size = htobe32(tx_size);

	/* set status indicating that the BMC is now active */
	status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
	rc = pwrite(astlpc->kcs_fd, &status, 1, KCS_REG_STATUS);
	if (rc != 1) {
		mctp_prwarn("KCS write failed");
		rc = -1;
	} else {
		rc = 0;
	}

	return rc;
}

static int mctp_astlpc_init_lpc(struct mctp_binding_astlpc *astlpc)
{
	struct aspeed_lpc_ctrl_mapping map = {
		.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
		.window_id = 0, /* There's only one */
		.flags = 0,
		.addr = 0,
		.offset = 0,
		.size = 0
	};
	int fd, rc;

	fd = open(lpc_path, O_RDWR | O_SYNC);
	if (fd < 0) {
		mctp_prwarn("LPC open (%s) failed", lpc_path);
		return -1;
	}

	rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map);
	if (rc) {
		mctp_prwarn("LPC GET_SIZE failed");
		close(fd);
		return -1;
	}

	astlpc->lpc_map_base = mmap(NULL, map.size, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, 0);
	if (astlpc->lpc_map_base == MAP_FAILED) {
		mctp_prwarn("LPC mmap failed");
		rc = -1;
	} else {
		astlpc->lpc_map = astlpc->lpc_map_base +
			map.size - LPC_WIN_SIZE;
	}

	close(fd);

	return rc;
}

static int mctp_astlpc_init_kcs(struct mctp_binding_astlpc *astlpc)
{
	astlpc->kcs_fd = open(kcs_path, O_RDWR);
	if (astlpc->kcs_fd < 0)
		return -1;

	return 0;
}

struct mctp_binding_astlpc *mctp_astlpc_init(void)
{
	struct mctp_binding_astlpc *astlpc;
	int rc;

	astlpc = __mctp_alloc(sizeof(*astlpc));
	memset(astlpc, 0, sizeof(*astlpc));
	astlpc->binding.name = "astlpc";
	astlpc->binding.version = 1;
	astlpc->binding.tx = mctp_binding_astlpc_tx;

	rc = mctp_astlpc_init_lpc(astlpc);
	if (rc) {
		free(astlpc);
		return NULL;
	}

	rc = mctp_astlpc_init_kcs(astlpc);
	if (rc) {
		free(astlpc);
		return NULL;
	}

	rc = mctp_astlpc_init_bmc(astlpc);
	if (rc) {
		free(astlpc);
		return NULL;
	}

	return astlpc;
}

