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

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#undef pr_fmt
#define pr_fmt(fmt) "core: " fmt

#include "libmctp.h"
#include "libmctp-alloc.h"
#include "libmctp-log.h"
#include "libmctp-cmds.h"
#include "range.h"
#include "compiler.h"

/* 64kb should be sufficient for a single message. Applications
 * requiring higher sizes can override by setting max_message_size.*/
#ifndef MCTP_MAX_MESSAGE_SIZE
#define MCTP_MAX_MESSAGE_SIZE 65536
#endif

/* Must be >= 2 for bridge busses */
#ifndef MCTP_MAX_BUSSES
#define MCTP_MAX_BUSSES 2
#endif

/* Concurrent reassembly contexts. */
#ifndef MCTP_REASSEMBLY_CTXS
#define MCTP_REASSEMBLY_CTXS 16
#endif

/* Outbound request tags */
#ifndef MCTP_REQ_TAGS
#define MCTP_REQ_TAGS MCTP_REASSEMBLY_CTXS
#endif

/* Internal data structures */

enum mctp_bus_state {
	mctp_bus_state_constructed = 0,
	mctp_bus_state_tx_enabled,
	mctp_bus_state_tx_disabled,
};

struct mctp_bus {
	mctp_eid_t eid;
	struct mctp_binding *binding;
	enum mctp_bus_state state;
	struct mctp *mctp;

	/* Current message to transmit */
	void *tx_msg;
	/* Position in tx_msg */
	size_t tx_msgpos;
	/* Length of tx_msg */
	size_t tx_msglen;
	/* Length of current packet payload */
	size_t tx_pktlen;
	uint8_t tx_seq;
	uint8_t tx_src;
	uint8_t tx_dest;
	bool tx_to;
	uint8_t tx_tag;

	/* todo: routing */
};

struct mctp_msg_ctx {
	/* NULL buf indicates an unused mctp_msg_ctx */
	void *buf;

	uint8_t src;
	uint8_t dest;
	uint8_t tag;
	uint8_t last_seq;
	size_t buf_size;
	size_t buf_alloc_size;
	size_t fragment_size;
};

struct mctp_req_tag {
	/* 0 is an unused entry */
	mctp_eid_t local;
	mctp_eid_t remote;
	uint8_t tag;
};

struct mctp {
	int n_busses;
	struct mctp_bus busses[MCTP_MAX_BUSSES];

	/* Message RX callback */
	mctp_rx_fn message_rx;
	void *message_rx_data;

	/* Packet capture callback */
	mctp_capture_fn capture;
	void *capture_data;

	/* Message reassembly. */
	struct mctp_msg_ctx msg_ctxs[MCTP_REASSEMBLY_CTXS];

	/* Allocated outbound TO tags */
	struct mctp_req_tag req_tags[MCTP_REQ_TAGS];
	/* used to avoid always allocating tag 0 */
	uint8_t tag_round_robin;

	enum {
		ROUTE_ENDPOINT,
		ROUTE_BRIDGE,
	} route_policy;
	size_t max_message_size;

	void *alloc_ctx;
};

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif

static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
				  mctp_eid_t dest, bool tag_owner,
				  uint8_t msg_tag, void *msg, size_t msg_len);
static void mctp_dealloc_tag(struct mctp_bus *bus, mctp_eid_t local,
			     mctp_eid_t remote, uint8_t tag);

struct mctp_pktbuf *mctp_pktbuf_alloc(struct mctp_binding *binding, size_t len)
{
	size_t size =
		binding->pkt_size + binding->pkt_header + binding->pkt_trailer;
	if (len > size) {
		return NULL;
	}

	void *storage = __mctp_alloc(size + sizeof(struct mctp_pktbuf));
	if (!storage) {
		return NULL;
	}
	struct mctp_pktbuf *pkt = mctp_pktbuf_init(binding, storage);
	pkt->alloc = true;
	pkt->end = pkt->start + len;
	return pkt;
}

void mctp_pktbuf_free(struct mctp_pktbuf *pkt)
{
	if (pkt->alloc) {
		__mctp_free(pkt);
	} else {
		mctp_prdebug("pktbuf_free called for non-alloced");
	}
}

struct mctp_pktbuf *mctp_pktbuf_init(struct mctp_binding *binding,
				     void *storage)
{
	size_t size =
		binding->pkt_size + binding->pkt_header + binding->pkt_trailer;
	struct mctp_pktbuf *buf = (struct mctp_pktbuf *)storage;
	buf->size = size;
	buf->start = binding->pkt_header;
	buf->end = buf->start;
	buf->mctp_hdr_off = buf->start;
	buf->alloc = false;

	return buf;
}

struct mctp_hdr *mctp_pktbuf_hdr(struct mctp_pktbuf *pkt)
{
	return (struct mctp_hdr *)(pkt->data + pkt->mctp_hdr_off);
}

void *mctp_pktbuf_data(struct mctp_pktbuf *pkt)
{
	return pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr);
}

size_t mctp_pktbuf_size(const struct mctp_pktbuf *pkt)
{
	return pkt->end - pkt->start;
}

void *mctp_pktbuf_alloc_start(struct mctp_pktbuf *pkt, size_t size)
{
	assert(size <= pkt->start);
	pkt->start -= size;
	return pkt->data + pkt->start;
}

void *mctp_pktbuf_alloc_end(struct mctp_pktbuf *pkt, size_t size)
{
	void *buf;

	assert(size <= (pkt->size - pkt->end));
	buf = pkt->data + pkt->end;
	pkt->end += size;
	return buf;
}

int mctp_pktbuf_push(struct mctp_pktbuf *pkt, const void *data, size_t len)
{
	void *p;

	if (pkt->end + len > pkt->size)
		return -1;

	p = pkt->data + pkt->end;

	pkt->end += len;
	memcpy(p, data, len);

	return 0;
}

void *mctp_pktbuf_pop(struct mctp_pktbuf *pkt, size_t len)
{
	if (len > mctp_pktbuf_size(pkt))
		return NULL;

	pkt->end -= len;
	return pkt->data + pkt->end;
}

/* Allocate a duplicate of the message and copy it */
static void *mctp_msg_dup(const void *msg, size_t msg_len, struct mctp *mctp)
{
	void *copy = __mctp_msg_alloc(msg_len, mctp);
	if (!copy) {
		mctp_prdebug("msg dup len %zu failed", msg_len);
		return NULL;
	}

	memcpy(copy, msg, msg_len);
	return copy;
}

/* Message reassembly */
static struct mctp_msg_ctx *mctp_msg_ctx_lookup(struct mctp *mctp, uint8_t src,
						uint8_t dest, uint8_t tag)
{
	unsigned int i;

	/* @todo: better lookup, if we add support for more outstanding
	 * message contexts */
	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *ctx = &mctp->msg_ctxs[i];
		if (ctx->buf && ctx->src == src && ctx->dest == dest &&
		    ctx->tag == tag)
			return ctx;
	}

	return NULL;
}

static struct mctp_msg_ctx *mctp_msg_ctx_create(struct mctp *mctp, uint8_t src,
						uint8_t dest, uint8_t tag)
{
	struct mctp_msg_ctx *ctx = NULL;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i];
		if (!tmp->buf) {
			ctx = tmp;
			break;
		}
	}

	if (!ctx)
		return NULL;

	ctx->src = src;
	ctx->dest = dest;
	ctx->tag = tag;

	ctx->buf_size = 0;
	ctx->buf_alloc_size = mctp->max_message_size;
	ctx->buf = __mctp_msg_alloc(ctx->buf_alloc_size, mctp);
	if (!ctx->buf) {
		return NULL;
	}

	return ctx;
}

static void mctp_msg_ctx_drop(struct mctp_bus *bus, struct mctp_msg_ctx *ctx)
{
	/* Free and mark as unused */
	__mctp_msg_free(ctx->buf, bus->mctp);
	ctx->buf = NULL;
}

static void mctp_msg_ctx_reset(struct mctp_msg_ctx *ctx)
{
	ctx->buf_size = 0;
	ctx->fragment_size = 0;
}

static int mctp_msg_ctx_add_pkt(struct mctp_msg_ctx *ctx,
				struct mctp_pktbuf *pkt)
{
	size_t len;

	len = mctp_pktbuf_size(pkt) - sizeof(struct mctp_hdr);

	if (len + ctx->buf_size < ctx->buf_size) {
		return -1;
	}

	if (ctx->buf_size + len > ctx->buf_alloc_size) {
		return -1;
	}

	memcpy((uint8_t *)ctx->buf + ctx->buf_size, mctp_pktbuf_data(pkt), len);
	ctx->buf_size += len;

	return 0;
}

/* Core API functions */
struct mctp *mctp_init(void)
{
	struct mctp *mctp;

	mctp = __mctp_alloc(sizeof(*mctp));

	if (!mctp)
		return NULL;

	mctp_setup(mctp);
	return mctp;
}

void mctp_setup(struct mctp *mctp)
{
	memset(mctp, 0, sizeof(*mctp));
	mctp->max_message_size = MCTP_MAX_MESSAGE_SIZE;
}

void mctp_set_max_message_size(struct mctp *mctp, size_t message_size)
{
	mctp->max_message_size = message_size;
}

void mctp_set_capture_handler(struct mctp *mctp, mctp_capture_fn fn, void *user)
{
	mctp->capture = fn;
	mctp->capture_data = user;
}

static void mctp_bus_destroy(struct mctp_bus *bus, struct mctp *mctp)
{
	if (bus->tx_msg) {
		__mctp_msg_free(bus->tx_msg, mctp);
		bus->tx_msg = NULL;
	}
}

void mctp_cleanup(struct mctp *mctp)
{
	size_t i;

	/* Cleanup message assembly contexts */
	static_assert(ARRAY_SIZE(mctp->msg_ctxs) < SIZE_MAX, "size");
	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i];
		if (tmp->buf)
			__mctp_msg_free(tmp->buf, mctp);
	}

	while (mctp->n_busses--)
		mctp_bus_destroy(&mctp->busses[mctp->n_busses], mctp);
}

void mctp_destroy(struct mctp *mctp)
{
	mctp_cleanup(mctp);
	__mctp_free(mctp);
}

int mctp_set_rx_all(struct mctp *mctp, mctp_rx_fn fn, void *data)
{
	mctp->message_rx = fn;
	mctp->message_rx_data = data;
	return 0;
}

static struct mctp_bus *find_bus_for_eid(struct mctp *mctp, mctp_eid_t dest
					 __attribute__((unused)))
{
	if (mctp->n_busses == 0)
		return NULL;

	/* for now, just use the first bus. For full routing support,
	 * we will need a table of neighbours */
	return &mctp->busses[0];
}

int mctp_register_bus(struct mctp *mctp, struct mctp_binding *binding,
		      mctp_eid_t eid)
{
	int rc = 0;

	/* todo: multiple busses */
	static_assert(MCTP_MAX_BUSSES >= 1, "need a bus");
	assert(mctp->n_busses == 0);
	mctp->n_busses = 1;

	assert(binding->tx_storage);

	memset(mctp->busses, 0, sizeof(struct mctp_bus));
	mctp->busses[0].mctp = mctp;
	mctp->busses[0].binding = binding;
	mctp->busses[0].eid = eid;
	binding->bus = &mctp->busses[0];
	binding->mctp = mctp;
	mctp->route_policy = ROUTE_ENDPOINT;

	if (binding->start) {
		rc = binding->start(binding);
		if (rc < 0) {
			mctp_prerr("Failed to start binding: %d", rc);
			binding->bus = NULL;
			mctp->n_busses = 0;
		}
	}

	return rc;
}

void mctp_unregister_bus(struct mctp *mctp, struct mctp_binding *binding)
{
	/*
	 * We only support one bus right now; once the call completes we will
	 * have no more busses
	 */
	mctp->n_busses = 0;
	binding->mctp = NULL;
	binding->bus = NULL;
}

int mctp_bridge_busses(struct mctp *mctp, struct mctp_binding *b1,
		       struct mctp_binding *b2)
{
	int rc = 0;

	assert(b1->tx_storage);
	assert(b2->tx_storage);

	assert(mctp->n_busses == 0);
	assert(MCTP_MAX_BUSSES >= 2);
	memset(mctp->busses, 0, 2 * sizeof(struct mctp_bus));
	mctp->n_busses = 2;
	mctp->busses[0].binding = b1;
	b1->bus = &mctp->busses[0];
	b1->mctp = mctp;
	mctp->busses[1].binding = b2;
	b2->bus = &mctp->busses[1];
	b2->mctp = mctp;

	mctp->route_policy = ROUTE_BRIDGE;

	if (b1->start) {
		rc = b1->start(b1);
		if (rc < 0) {
			mctp_prerr("Failed to start bridged bus %s: %d",
				   b1->name, rc);
			goto done;
		}
	}

	if (b2->start) {
		rc = b2->start(b2);
		if (rc < 0) {
			mctp_prerr("Failed to start bridged bus %s: %d",
				   b2->name, rc);
			goto done;
		}
	}

done:
	return rc;
}

static inline bool mctp_ctrl_cmd_is_transport(struct mctp_ctrl_msg_hdr *hdr)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
	return ((hdr->command_code >= MCTP_CTRL_CMD_FIRST_TRANSPORT) &&
		(hdr->command_code <= MCTP_CTRL_CMD_LAST_TRANSPORT));
#pragma GCC diagnostic pop
}

static bool mctp_ctrl_handle_msg(struct mctp_bus *bus, mctp_eid_t src,
				 uint8_t msg_tag, bool tag_owner, void *buffer,
				 size_t length)
{
	struct mctp_ctrl_msg_hdr *msg_hdr = buffer;

	/*
	 * Control message is received. If a transport control message handler
	 * is provided, it will called. If there is no dedicated handler, this
	 * function returns false and data can be handled by the generic
	 * message handler. The transport control message handler will be
	 * provided with messages in the command range 0xF0 - 0xFF.
	 */
	if (mctp_ctrl_cmd_is_transport(msg_hdr)) {
		if (bus->binding->control_rx != NULL) {
			/* MCTP bus binding handler */
			bus->binding->control_rx(src, msg_tag, tag_owner,
						 bus->binding->control_rx_data,
						 buffer, length);
			return true;
		}
	}

	/*
	 * Command was not handled, due to lack of specific callback.
	 * It will be passed to regular message_rx handler.
	 */
	return false;
}

static inline bool mctp_rx_dest_is_local(struct mctp_bus *bus, mctp_eid_t dest)
{
	return dest == bus->eid || dest == MCTP_EID_NULL ||
	       dest == MCTP_EID_BROADCAST;
}

static inline bool mctp_ctrl_cmd_is_request(struct mctp_ctrl_msg_hdr *hdr)
{
	return hdr->ic_msg_type == MCTP_CTRL_HDR_MSG_TYPE &&
	       hdr->rq_dgram_inst & MCTP_CTRL_HDR_FLAG_REQUEST;
}

/*
 * Receive the complete MCTP message and route it.
 * Asserts:
 *     'buf' is not NULL.
 */
static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, mctp_eid_t src,
		    mctp_eid_t dest, bool tag_owner, uint8_t msg_tag, void *buf,
		    size_t len)
{
	assert(buf != NULL);

	if (mctp->route_policy == ROUTE_ENDPOINT &&
	    mctp_rx_dest_is_local(bus, dest)) {
		/* Note responses to allocated tags */
		if (!tag_owner) {
			mctp_dealloc_tag(bus, dest, src, msg_tag);
		}

		/* Handle MCTP Control Messages: */
		if (len >= sizeof(struct mctp_ctrl_msg_hdr)) {
			struct mctp_ctrl_msg_hdr *msg_hdr = buf;

			/*
			 * Identify if this is a control request message.
			 * See DSP0236 v1.3.0 sec. 11.5.
			 */
			if (mctp_ctrl_cmd_is_request(msg_hdr)) {
				bool handled;
				handled = mctp_ctrl_handle_msg(
					bus, src, msg_tag, tag_owner, buf, len);
				if (handled)
					return;
			}
		}

		if (mctp->message_rx)
			mctp->message_rx(src, tag_owner, msg_tag,
					 mctp->message_rx_data, buf, len);
	}

	if (mctp->route_policy == ROUTE_BRIDGE) {
		int i;

		for (i = 0; i < mctp->n_busses; i++) {
			struct mctp_bus *dest_bus = &mctp->busses[i];
			if (dest_bus == bus)
				continue;

			void *copy = mctp_msg_dup(buf, len, mctp);
			if (!copy) {
				return;
			}

			mctp_message_tx_on_bus(dest_bus, src, dest, tag_owner,
					       msg_tag, copy, len);
		}
	}
}

void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt)
{
	struct mctp_bus *bus = binding->bus;
	struct mctp *mctp = binding->mctp;
	uint8_t flags, exp_seq, seq, tag;
	struct mctp_msg_ctx *ctx;
	struct mctp_hdr *hdr;
	bool tag_owner;
	size_t len;
	void *p;
	int rc;

	assert(bus);

	/* Drop packet if it was smaller than mctp hdr size */
	if (mctp_pktbuf_size(pkt) < sizeof(struct mctp_hdr))
		goto out;

	if (mctp->capture)
		mctp->capture(pkt, MCTP_MESSAGE_CAPTURE_INCOMING,
			      mctp->capture_data);

	hdr = mctp_pktbuf_hdr(pkt);

	/* small optimisation: don't bother reassembly if we're going to
	 * drop the packet in mctp_rx anyway */
	if (mctp->route_policy == ROUTE_ENDPOINT &&
	    !mctp_rx_dest_is_local(bus, hdr->dest))
		goto out;

	flags = hdr->flags_seq_tag & (MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM);
	tag = (hdr->flags_seq_tag >> MCTP_HDR_TAG_SHIFT) & MCTP_HDR_TAG_MASK;
	seq = (hdr->flags_seq_tag >> MCTP_HDR_SEQ_SHIFT) & MCTP_HDR_SEQ_MASK;
	tag_owner = (hdr->flags_seq_tag >> MCTP_HDR_TO_SHIFT) &
		    MCTP_HDR_TO_MASK;

	switch (flags) {
	case MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM:
		/* single-packet message - send straight up to rx function,
		 * no need to create a message context */
		len = pkt->end - pkt->mctp_hdr_off - sizeof(struct mctp_hdr);
		p = mctp_msg_dup(pkt->data + pkt->mctp_hdr_off +
					 sizeof(struct mctp_hdr),
				 len, mctp);
		if (p) {
			mctp_rx(mctp, bus, hdr->src, hdr->dest, tag_owner, tag,
				p, len);
			__mctp_msg_free(p, mctp);
		}
		break;

	case MCTP_HDR_FLAG_SOM:
		/* start of a new message - start the new context for
		 * future message reception. If an existing context is
		 * already present, drop it. */
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (ctx) {
			mctp_msg_ctx_reset(ctx);
		} else {
			ctx = mctp_msg_ctx_create(mctp, hdr->src, hdr->dest,
						  tag);
			/* If context creation fails due to exhaution of contexts we
			* can support, drop the packet */
			if (!ctx) {
				mctp_prdebug("Context buffers exhausted.");
				goto out;
			}
		}

		/* Save the fragment size, subsequent middle fragments
		 * should of the same size */
		ctx->fragment_size = mctp_pktbuf_size(pkt);

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (rc) {
			mctp_msg_ctx_drop(bus, ctx);
		} else {
			ctx->last_seq = seq;
		}

		break;

	case MCTP_HDR_FLAG_EOM:
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (!ctx)
			goto out;

		exp_seq = (ctx->last_seq + 1) % 4;

		if (exp_seq != seq) {
			mctp_prdebug(
				"Sequence number %d does not match expected %d",
				seq, exp_seq);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		len = mctp_pktbuf_size(pkt);

		if (len > ctx->fragment_size) {
			mctp_prdebug("Unexpected fragment size. Expected"
				     " less than %zu, received = %zu",
				     ctx->fragment_size, len);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (!rc)
			mctp_rx(mctp, bus, ctx->src, ctx->dest, tag_owner, tag,
				ctx->buf, ctx->buf_size);

		mctp_msg_ctx_drop(bus, ctx);
		break;

	case 0:
		/* Neither SOM nor EOM */
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (!ctx)
			goto out;

		exp_seq = (ctx->last_seq + 1) % 4;
		if (exp_seq != seq) {
			mctp_prdebug(
				"Sequence number %d does not match expected %d",
				seq, exp_seq);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		len = mctp_pktbuf_size(pkt);

		if (len != ctx->fragment_size) {
			mctp_prdebug("Unexpected fragment size. Expected = %zu "
				     "received = %zu",
				     ctx->fragment_size, len);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (rc) {
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}
		ctx->last_seq = seq;

		break;
	}
out:
	return;
}

static int mctp_packet_tx(struct mctp_bus *bus, struct mctp_pktbuf *pkt)
{
	struct mctp *mctp = bus->binding->mctp;

	if (bus->state != mctp_bus_state_tx_enabled) {
		mctp_prdebug("tx with bus disabled");
		return -1;
	}

	if (mctp->capture)
		mctp->capture(pkt, MCTP_MESSAGE_CAPTURE_OUTGOING,
			      mctp->capture_data);

	return bus->binding->tx(bus->binding, pkt);
}

/* Returns a pointer to the binding's tx_storage */
static struct mctp_pktbuf *mctp_next_tx_pkt(struct mctp_bus *bus)
{
	if (!bus->tx_msg) {
		return NULL;
	}

	size_t p = bus->tx_msgpos;
	size_t msg_len = bus->tx_msglen;
	size_t payload_len = msg_len - p;
	size_t max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size);
	if (payload_len > max_payload_len)
		payload_len = max_payload_len;

	struct mctp_pktbuf *pkt =
		mctp_pktbuf_init(bus->binding, bus->binding->tx_storage);
	struct mctp_hdr *hdr = mctp_pktbuf_hdr(pkt);

	hdr->ver = bus->binding->version & 0xf;
	hdr->dest = bus->tx_dest;
	hdr->src = bus->tx_src;
	hdr->flags_seq_tag = (bus->tx_to << MCTP_HDR_TO_SHIFT) |
			     (bus->tx_tag << MCTP_HDR_TAG_SHIFT);

	if (p == 0)
		hdr->flags_seq_tag |= MCTP_HDR_FLAG_SOM;
	if (p + payload_len >= msg_len)
		hdr->flags_seq_tag |= MCTP_HDR_FLAG_EOM;
	hdr->flags_seq_tag |= bus->tx_seq << MCTP_HDR_SEQ_SHIFT;

	memcpy(mctp_pktbuf_data(pkt), (uint8_t *)bus->tx_msg + p, payload_len);
	pkt->end = pkt->start + sizeof(*hdr) + payload_len;
	bus->tx_pktlen = payload_len;

	mctp_prdebug(
		"tx dst %d tag %d payload len %zu seq %d. msg pos %zu len %zu",
		hdr->dest, bus->tx_tag, payload_len, bus->tx_seq, p, msg_len);

	return pkt;
}

/* Called when a packet has successfully been sent */
static void mctp_tx_complete(struct mctp_bus *bus)
{
	if (!bus->tx_msg) {
		mctp_prdebug("tx complete no message");
		return;
	}

	bus->tx_seq = (bus->tx_seq + 1) & MCTP_HDR_SEQ_MASK;
	bus->tx_msgpos += bus->tx_pktlen;

	if (bus->tx_msgpos >= bus->tx_msglen) {
		__mctp_msg_free(bus->tx_msg, bus->binding->mctp);
		bus->tx_msg = NULL;
	}
}

static void mctp_send_tx_queue(struct mctp_bus *bus)
{
	struct mctp_pktbuf *pkt;

	while (bus->tx_msg && bus->state == mctp_bus_state_tx_enabled) {
		int rc;

		pkt = mctp_next_tx_pkt(bus);

		rc = mctp_packet_tx(bus, pkt);
		switch (rc) {
		/* If transmission succeded */
		case 0:
			/* Drop the packet */
			mctp_tx_complete(bus);
			break;

		/* If the binding was busy */
		case -EBUSY:
			/* Keep the packet for next try */
			mctp_prdebug("tx EBUSY");
			return;

		/* Some other unknown error occurred */
		default:
			/* Drop the packet */
			mctp_prdebug("tx drop %d", rc);
			mctp_tx_complete(bus);
			return;
		};
	}
}

void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable)
{
	struct mctp_bus *bus = binding->bus;

	switch (bus->state) {
	case mctp_bus_state_constructed:
		if (!enable)
			return;

		if (binding->pkt_size < MCTP_PACKET_SIZE(MCTP_BTU)) {
			mctp_prerr(
				"Cannot start %s binding with invalid MTU: %zu",
				binding->name,
				MCTP_BODY_SIZE(binding->pkt_size));
			return;
		}

		bus->state = mctp_bus_state_tx_enabled;
		mctp_prinfo("%s binding started", binding->name);
		return;
	case mctp_bus_state_tx_enabled:
		if (enable)
			return;

		bus->state = mctp_bus_state_tx_disabled;
		mctp_prdebug("%s binding Tx disabled", binding->name);
		return;
	case mctp_bus_state_tx_disabled:
		if (!enable)
			return;

		bus->state = mctp_bus_state_tx_enabled;
		mctp_prdebug("%s binding Tx enabled", binding->name);
		mctp_send_tx_queue(bus);
		return;
	}
}

static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
				  mctp_eid_t dest, bool tag_owner,
				  uint8_t msg_tag, void *msg, size_t msg_len)
{
	size_t max_payload_len;
	int rc;

	if (bus->state == mctp_bus_state_constructed) {
		rc = -ENXIO;
		goto err;
	}

	if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag) {
		rc = -EINVAL;
		goto err;
	}

	max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size);

	{
		const bool valid_mtu = max_payload_len >= MCTP_BTU;
		assert(valid_mtu);
		if (!valid_mtu) {
			rc = -EINVAL;
			goto err;
		}
	}

	mctp_prdebug(
		"%s: Generating packets for transmission of %zu byte message from %hhu to %hhu",
		__func__, msg_len, src, dest);

	if (bus->tx_msg) {
		mctp_prdebug("Bus busy");
		rc = -EBUSY;
		goto err;
	}

	/* Take the message to send */
	bus->tx_msg = msg;
	bus->tx_msglen = msg_len;
	bus->tx_msgpos = 0;
	/* bus->tx_seq is allowed to continue from previous message */
	bus->tx_src = src;
	bus->tx_dest = dest;
	bus->tx_to = tag_owner;
	bus->tx_tag = msg_tag;

	mctp_send_tx_queue(bus);
	return 0;

err:
	__mctp_msg_free(msg, bus->binding->mctp);
	return rc;
}

int mctp_message_tx_alloced(struct mctp *mctp, mctp_eid_t eid, bool tag_owner,
			    uint8_t msg_tag, void *msg, size_t msg_len)
{
	struct mctp_bus *bus;

	/* TODO: Protect against same tag being used across
	 * different callers */
	if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag) {
		mctp_prerr("Incorrect message tag %u passed.", msg_tag);
		__mctp_msg_free(msg, mctp);
		return -EINVAL;
	}

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		__mctp_msg_free(msg, mctp);
		return 0;
	}

	return mctp_message_tx_on_bus(bus, bus->eid, eid, tag_owner, msg_tag,
				      msg, msg_len);
}

int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid, bool tag_owner,
		    uint8_t msg_tag, const void *msg, size_t msg_len)
{
	void *copy = mctp_msg_dup(msg, msg_len, mctp);
	if (!copy) {
		return -ENOMEM;
	}

	return mctp_message_tx_alloced(mctp, eid, tag_owner, msg_tag, copy,
				       msg_len);
}

static void mctp_dealloc_tag(struct mctp_bus *bus, mctp_eid_t local,
			     mctp_eid_t remote, uint8_t tag)
{
	struct mctp *mctp = bus->binding->mctp;
	if (local == 0 || remote == 0) {
		return;
	}

	for (size_t i = 0; i < ARRAY_SIZE(mctp->req_tags); i++) {
		struct mctp_req_tag *r = &mctp->req_tags[i];
		if (r->local == local && r->remote == remote && r->tag == tag) {
			r->local = 0;
			r->remote = 0;
			r->tag = 0;
			return;
		}
	}
}

static int mctp_alloc_tag(struct mctp *mctp, mctp_eid_t local,
			  mctp_eid_t remote, uint8_t *ret_tag)
{
	assert(local != 0);
	assert(remote != 0);

	uint8_t used = 0;
	struct mctp_req_tag *spare = NULL;
	/* Find which tags and slots are used/spare */
	for (size_t i = 0; i < ARRAY_SIZE(mctp->req_tags); i++) {
		struct mctp_req_tag *r = &mctp->req_tags[i];
		if (r->local == 0) {
			spare = r;
		} else {
			// TODO: check timeouts
			if (r->local == local && r->remote == remote) {
				used |= 1 << r->tag;
			}
		}
	}

	if (spare == NULL) {
		// All req_tag slots are in-use
		return -EBUSY;
	}

	for (uint8_t t = 0; t < 8; t++) {
		uint8_t tag = (t + mctp->tag_round_robin) % 8;
		if ((used & 1 << tag) == 0) {
			spare->local = local;
			spare->remote = remote;
			spare->tag = tag;
			*ret_tag = tag;
			mctp->tag_round_robin = (tag + 1) % 8;
			return 0;
		}
	}

	// All 8 tags are used for this src/dest pair
	return -EBUSY;
}

int mctp_message_tx_request(struct mctp *mctp, mctp_eid_t eid, void *msg,
			    size_t msg_len, uint8_t *ret_alloc_msg_tag)
{
	int rc;
	struct mctp_bus *bus;

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		__mctp_msg_free(msg, mctp);
		return 0;
	}

	uint8_t alloc_tag;
	rc = mctp_alloc_tag(mctp, bus->eid, eid, &alloc_tag);
	if (rc) {
		mctp_prdebug("Failed allocating tag");
		__mctp_msg_free(msg, mctp);
		return rc;
	}

	if (ret_alloc_msg_tag) {
		*ret_alloc_msg_tag = alloc_tag;
	}

	return mctp_message_tx_alloced(mctp, eid, true, alloc_tag, msg,
				       msg_len);
}

bool mctp_is_tx_ready(struct mctp *mctp, mctp_eid_t eid)
{
	struct mctp_bus *bus;

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		return true;
	}
	return bus->tx_msg == NULL;
}

void *mctp_get_alloc_ctx(struct mctp *mctp)
{
	return mctp->alloc_ctx;
}

void mctp_set_alloc_ctx(struct mctp *mctp, void *ctx)
{
	mctp->alloc_ctx = ctx;
}
