// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2019 Netronome Systems, Inc. */

#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/skbuff.h>

#include "ccm.h"
#include "nfp_net.h"

/* CCM messages via the mailbox.  CMSGs get wrapped into simple TLVs
 * and copied into the mailbox.  Multiple messages can be copied to
 * form a batch.  Threads come in with CMSG formed in an skb, then
 * enqueue that skb onto the request queue.  If threads skb is first
 * in queue this thread will handle the mailbox operation.  It copies
 * up to 64 messages into the mailbox (making sure that both requests
 * and replies will fit.  After FW is done processing the batch it
 * copies the data out and wakes waiting threads.
 * If a thread is waiting it either gets its the message completed
 * (response is copied into the same skb as the request, overwriting
 * it), or becomes the first in queue.
 * Completions and next-to-run are signaled via the control buffer
 * to limit potential cache line bounces.
 */

#define NFP_CCM_MBOX_BATCH_LIMIT	64
#define NFP_CCM_TIMEOUT			(NFP_NET_POLL_TIMEOUT * 1000)
#define NFP_CCM_MAX_QLEN		1024

enum nfp_net_mbox_cmsg_state {
	NFP_NET_MBOX_CMSG_STATE_QUEUED,
	NFP_NET_MBOX_CMSG_STATE_NEXT,
	NFP_NET_MBOX_CMSG_STATE_BUSY,
	NFP_NET_MBOX_CMSG_STATE_REPLY_FOUND,
	NFP_NET_MBOX_CMSG_STATE_DONE,
};

/**
 * struct nfp_ccm_mbox_cmsg_cb - CCM mailbox specific info
 * @state:	processing state (/stage) of the message
 * @err:	error encountered during processing if any
 * @max_len:	max(request_len, reply_len)
 * @exp_reply:	expected reply length (0 means don't validate)
 * @posted:	the message was posted and nobody waits for the reply
 */
struct nfp_ccm_mbox_cmsg_cb {
	enum nfp_net_mbox_cmsg_state state;
	int err;
	unsigned int max_len;
	unsigned int exp_reply;
	bool posted;
};

static u32 nfp_ccm_mbox_max_msg(struct nfp_net *nn)
{
	return round_down(nn->tlv_caps.mbox_len, 4) -
		NFP_NET_CFG_MBOX_SIMPLE_VAL - /* common mbox command header */
		4 * 2; /* Msg TLV plus End TLV headers */
}

static void
nfp_ccm_mbox_msg_init(struct sk_buff *skb, unsigned int exp_reply, int max_len)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	cb->state = NFP_NET_MBOX_CMSG_STATE_QUEUED;
	cb->err = 0;
	cb->max_len = max_len;
	cb->exp_reply = exp_reply;
	cb->posted = false;
}

static int nfp_ccm_mbox_maxlen(const struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	return cb->max_len;
}

static bool nfp_ccm_mbox_done(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	return cb->state == NFP_NET_MBOX_CMSG_STATE_DONE;
}

static bool nfp_ccm_mbox_in_progress(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	return cb->state != NFP_NET_MBOX_CMSG_STATE_QUEUED &&
	       cb->state != NFP_NET_MBOX_CMSG_STATE_NEXT;
}

static void nfp_ccm_mbox_set_busy(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	cb->state = NFP_NET_MBOX_CMSG_STATE_BUSY;
}

static bool nfp_ccm_mbox_is_posted(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	return cb->posted;
}

static void nfp_ccm_mbox_mark_posted(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	cb->posted = true;
}

static bool nfp_ccm_mbox_is_first(struct nfp_net *nn, struct sk_buff *skb)
{
	return skb_queue_is_first(&nn->mbox_cmsg.queue, skb);
}

static bool nfp_ccm_mbox_should_run(struct nfp_net *nn, struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	return cb->state == NFP_NET_MBOX_CMSG_STATE_NEXT;
}

static void nfp_ccm_mbox_mark_next_runner(struct nfp_net *nn)
{
	struct nfp_ccm_mbox_cmsg_cb *cb;
	struct sk_buff *skb;

	skb = skb_peek(&nn->mbox_cmsg.queue);
	if (!skb)
		return;

	cb = (void *)skb->cb;
	cb->state = NFP_NET_MBOX_CMSG_STATE_NEXT;
	if (cb->posted)
		queue_work(nn->mbox_cmsg.workq, &nn->mbox_cmsg.runq_work);
}

static void
nfp_ccm_mbox_write_tlv(struct nfp_net *nn, u32 off, u32 type, u32 len)
{
	nn_writel(nn, off,
		  FIELD_PREP(NFP_NET_MBOX_TLV_TYPE, type) |
		  FIELD_PREP(NFP_NET_MBOX_TLV_LEN, len));
}

static void nfp_ccm_mbox_copy_in(struct nfp_net *nn, struct sk_buff *last)
{
	struct sk_buff *skb;
	int reserve, i, cnt;
	__be32 *data;
	u32 off, len;

	off = nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL;
	skb = __skb_peek(&nn->mbox_cmsg.queue);
	while (true) {
		nfp_ccm_mbox_write_tlv(nn, off, NFP_NET_MBOX_TLV_TYPE_MSG,
				       skb->len);
		off += 4;

		/* Write data word by word, skb->data should be aligned */
		data = (__be32 *)skb->data;
		cnt = skb->len / 4;
		for (i = 0 ; i < cnt; i++) {
			nn_writel(nn, off, be32_to_cpu(data[i]));
			off += 4;
		}
		if (skb->len & 3) {
			__be32 tmp = 0;

			memcpy(&tmp, &data[i], skb->len & 3);
			nn_writel(nn, off, be32_to_cpu(tmp));
			off += 4;
		}

		/* Reserve space if reply is bigger */
		len = round_up(skb->len, 4);
		reserve = nfp_ccm_mbox_maxlen(skb) - len;
		if (reserve > 0) {
			nfp_ccm_mbox_write_tlv(nn, off,
					       NFP_NET_MBOX_TLV_TYPE_RESV,
					       reserve);
			off += 4 + reserve;
		}

		if (skb == last)
			break;
		skb = skb_queue_next(&nn->mbox_cmsg.queue, skb);
	}

	nfp_ccm_mbox_write_tlv(nn, off, NFP_NET_MBOX_TLV_TYPE_END, 0);
}

static struct sk_buff *
nfp_ccm_mbox_find_req(struct nfp_net *nn, __be16 tag, struct sk_buff *last)
{
	struct sk_buff *skb;

	skb = __skb_peek(&nn->mbox_cmsg.queue);
	while (true) {
		if (__nfp_ccm_get_tag(skb) == tag)
			return skb;

		if (skb == last)
			return NULL;
		skb = skb_queue_next(&nn->mbox_cmsg.queue, skb);
	}
}

static void nfp_ccm_mbox_copy_out(struct nfp_net *nn, struct sk_buff *last)
{
	struct nfp_ccm_mbox_cmsg_cb *cb;
	u8 __iomem *data, *end;
	struct sk_buff *skb;

	data = nn->dp.ctrl_bar + nn->tlv_caps.mbox_off +
		NFP_NET_CFG_MBOX_SIMPLE_VAL;
	end = data + nn->tlv_caps.mbox_len;

	while (true) {
		unsigned int length, offset, type;
		struct nfp_ccm_hdr hdr;
		u32 tlv_hdr;

		tlv_hdr = readl(data);
		type = FIELD_GET(NFP_NET_MBOX_TLV_TYPE, tlv_hdr);
		length = FIELD_GET(NFP_NET_MBOX_TLV_LEN, tlv_hdr);
		offset = data - nn->dp.ctrl_bar;

		/* Advance past the header */
		data += 4;

		if (data + length > end) {
			nn_dp_warn(&nn->dp, "mailbox oversized TLV type:%d offset:%u len:%u\n",
				   type, offset, length);
			break;
		}

		if (type == NFP_NET_MBOX_TLV_TYPE_END)
			break;
		if (type == NFP_NET_MBOX_TLV_TYPE_RESV)
			goto next_tlv;
		if (type != NFP_NET_MBOX_TLV_TYPE_MSG &&
		    type != NFP_NET_MBOX_TLV_TYPE_MSG_NOSUP) {
			nn_dp_warn(&nn->dp, "mailbox unknown TLV type:%d offset:%u len:%u\n",
				   type, offset, length);
			break;
		}

		if (length < 4) {
			nn_dp_warn(&nn->dp, "mailbox msg too short to contain header TLV type:%d offset:%u len:%u\n",
				   type, offset, length);
			break;
		}

		hdr.raw = cpu_to_be32(readl(data));

		skb = nfp_ccm_mbox_find_req(nn, hdr.tag, last);
		if (!skb) {
			nn_dp_warn(&nn->dp, "mailbox request not found:%u\n",
				   be16_to_cpu(hdr.tag));
			break;
		}
		cb = (void *)skb->cb;

		if (type == NFP_NET_MBOX_TLV_TYPE_MSG_NOSUP) {
			nn_dp_warn(&nn->dp,
				   "mailbox msg not supported type:%d\n",
				   nfp_ccm_get_type(skb));
			cb->err = -EIO;
			goto next_tlv;
		}

		if (hdr.type != __NFP_CCM_REPLY(nfp_ccm_get_type(skb))) {
			nn_dp_warn(&nn->dp, "mailbox msg reply wrong type:%u expected:%lu\n",
				   hdr.type,
				   __NFP_CCM_REPLY(nfp_ccm_get_type(skb)));
			cb->err = -EIO;
			goto next_tlv;
		}
		if (cb->exp_reply && length != cb->exp_reply) {
			nn_dp_warn(&nn->dp, "mailbox msg reply wrong size type:%u expected:%u have:%u\n",
				   hdr.type, length, cb->exp_reply);
			cb->err = -EIO;
			goto next_tlv;
		}
		if (length > cb->max_len) {
			nn_dp_warn(&nn->dp, "mailbox msg oversized reply type:%u max:%u have:%u\n",
				   hdr.type, cb->max_len, length);
			cb->err = -EIO;
			goto next_tlv;
		}

		if (!cb->posted) {
			__be32 *skb_data;
			int i, cnt;

			if (length <= skb->len)
				__skb_trim(skb, length);
			else
				skb_put(skb, length - skb->len);

			/* We overcopy here slightly, but that's okay,
			 * the skb is large enough, and the garbage will
			 * be ignored (beyond skb->len).
			 */
			skb_data = (__be32 *)skb->data;
			memcpy(skb_data, &hdr, 4);

			cnt = DIV_ROUND_UP(length, 4);
			for (i = 1 ; i < cnt; i++)
				skb_data[i] = cpu_to_be32(readl(data + i * 4));
		}

		cb->state = NFP_NET_MBOX_CMSG_STATE_REPLY_FOUND;
next_tlv:
		data += round_up(length, 4);
		if (data + 4 > end) {
			nn_dp_warn(&nn->dp,
				   "reached end of MBOX without END TLV\n");
			break;
		}
	}

	smp_wmb(); /* order the skb->data vs. cb->state */
	spin_lock_bh(&nn->mbox_cmsg.queue.lock);
	do {
		skb = __skb_dequeue(&nn->mbox_cmsg.queue);
		cb = (void *)skb->cb;

		if (cb->state != NFP_NET_MBOX_CMSG_STATE_REPLY_FOUND) {
			cb->err = -ENOENT;
			smp_wmb(); /* order the cb->err vs. cb->state */
		}
		cb->state = NFP_NET_MBOX_CMSG_STATE_DONE;

		if (cb->posted) {
			if (cb->err)
				nn_dp_warn(&nn->dp,
					   "mailbox posted msg failed type:%u err:%d\n",
					   nfp_ccm_get_type(skb), cb->err);
			dev_consume_skb_any(skb);
		}
	} while (skb != last);

	nfp_ccm_mbox_mark_next_runner(nn);
	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);
}

static void
nfp_ccm_mbox_mark_all_err(struct nfp_net *nn, struct sk_buff *last, int err)
{
	struct nfp_ccm_mbox_cmsg_cb *cb;
	struct sk_buff *skb;

	spin_lock_bh(&nn->mbox_cmsg.queue.lock);
	do {
		skb = __skb_dequeue(&nn->mbox_cmsg.queue);
		cb = (void *)skb->cb;

		cb->err = err;
		smp_wmb(); /* order the cb->err vs. cb->state */
		cb->state = NFP_NET_MBOX_CMSG_STATE_DONE;
	} while (skb != last);

	nfp_ccm_mbox_mark_next_runner(nn);
	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);
}

static void nfp_ccm_mbox_run_queue_unlock(struct nfp_net *nn)
	__releases(&nn->mbox_cmsg.queue.lock)
{
	int space = nn->tlv_caps.mbox_len - NFP_NET_CFG_MBOX_SIMPLE_VAL;
	struct sk_buff *skb, *last;
	int cnt, err;

	space -= 4; /* for End TLV */

	/* First skb must fit, because it's ours and we checked it fits */
	cnt = 1;
	last = skb = __skb_peek(&nn->mbox_cmsg.queue);
	space -= 4 + nfp_ccm_mbox_maxlen(skb);

	while (!skb_queue_is_last(&nn->mbox_cmsg.queue, last)) {
		skb = skb_queue_next(&nn->mbox_cmsg.queue, last);
		space -= 4 + nfp_ccm_mbox_maxlen(skb);
		if (space < 0)
			break;
		last = skb;
		nfp_ccm_mbox_set_busy(skb);
		cnt++;
		if (cnt == NFP_CCM_MBOX_BATCH_LIMIT)
			break;
	}
	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);

	/* Now we own all skb's marked in progress, new requests may arrive
	 * at the end of the queue.
	 */

	nn_ctrl_bar_lock(nn);

	nfp_ccm_mbox_copy_in(nn, last);

	err = nfp_net_mbox_reconfig(nn, NFP_NET_CFG_MBOX_CMD_TLV_CMSG);
	if (!err)
		nfp_ccm_mbox_copy_out(nn, last);
	else
		nfp_ccm_mbox_mark_all_err(nn, last, -EIO);

	nn_ctrl_bar_unlock(nn);

	wake_up_all(&nn->mbox_cmsg.wq);
}

static int nfp_ccm_mbox_skb_return(struct sk_buff *skb)
{
	struct nfp_ccm_mbox_cmsg_cb *cb = (void *)skb->cb;

	if (cb->err)
		dev_kfree_skb_any(skb);
	return cb->err;
}

/* If wait timed out but the command is already in progress we have
 * to wait until it finishes.  Runners has ownership of the skbs marked
 * as busy.
 */
static int
nfp_ccm_mbox_unlink_unlock(struct nfp_net *nn, struct sk_buff *skb,
			   enum nfp_ccm_type type)
	__releases(&nn->mbox_cmsg.queue.lock)
{
	bool was_first;

	if (nfp_ccm_mbox_in_progress(skb)) {
		spin_unlock_bh(&nn->mbox_cmsg.queue.lock);

		wait_event(nn->mbox_cmsg.wq, nfp_ccm_mbox_done(skb));
		smp_rmb(); /* pairs with smp_wmb() after data is written */
		return nfp_ccm_mbox_skb_return(skb);
	}

	was_first = nfp_ccm_mbox_should_run(nn, skb);
	__skb_unlink(skb, &nn->mbox_cmsg.queue);
	if (was_first)
		nfp_ccm_mbox_mark_next_runner(nn);

	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);

	if (was_first)
		wake_up_all(&nn->mbox_cmsg.wq);

	nn_dp_warn(&nn->dp, "time out waiting for mbox response to 0x%02x\n",
		   type);
	return -ETIMEDOUT;
}

static int
nfp_ccm_mbox_msg_prepare(struct nfp_net *nn, struct sk_buff *skb,
			 enum nfp_ccm_type type,
			 unsigned int reply_size, unsigned int max_reply_size,
			 gfp_t flags)
{
	const unsigned int mbox_max = nfp_ccm_mbox_max_msg(nn);
	unsigned int max_len;
	ssize_t undersize;
	int err;

	if (unlikely(!(nn->tlv_caps.mbox_cmsg_types & BIT(type)))) {
		nn_dp_warn(&nn->dp,
			   "message type %d not supported by mailbox\n", type);
		return -EINVAL;
	}

	/* If the reply size is unknown assume it will take the entire
	 * mailbox, the callers should do their best for this to never
	 * happen.
	 */
	if (!max_reply_size)
		max_reply_size = mbox_max;
	max_reply_size = round_up(max_reply_size, 4);

	/* Make sure we can fit the entire reply into the skb,
	 * and that we don't have to slow down the mbox handler
	 * with allocations.
	 */
	undersize = max_reply_size - (skb_end_pointer(skb) - skb->data);
	if (undersize > 0) {
		err = pskb_expand_head(skb, 0, undersize, flags);
		if (err) {
			nn_dp_warn(&nn->dp,
				   "can't allocate reply buffer for mailbox\n");
			return err;
		}
	}

	/* Make sure that request and response both fit into the mailbox */
	max_len = max(max_reply_size, round_up(skb->len, 4));
	if (max_len > mbox_max) {
		nn_dp_warn(&nn->dp,
			   "message too big for tha mailbox: %u/%u vs %u\n",
			   skb->len, max_reply_size, mbox_max);
		return -EMSGSIZE;
	}

	nfp_ccm_mbox_msg_init(skb, reply_size, max_len);

	return 0;
}

static int
nfp_ccm_mbox_msg_enqueue(struct nfp_net *nn, struct sk_buff *skb,
			 enum nfp_ccm_type type, bool critical)
{
	struct nfp_ccm_hdr *hdr;

	assert_spin_locked(&nn->mbox_cmsg.queue.lock);

	if (!critical && nn->mbox_cmsg.queue.qlen >= NFP_CCM_MAX_QLEN) {
		nn_dp_warn(&nn->dp, "mailbox request queue too long\n");
		return -EBUSY;
	}

	hdr = (void *)skb->data;
	hdr->ver = NFP_CCM_ABI_VERSION;
	hdr->type = type;
	hdr->tag = cpu_to_be16(nn->mbox_cmsg.tag++);

	__skb_queue_tail(&nn->mbox_cmsg.queue, skb);

	return 0;
}

int __nfp_ccm_mbox_communicate(struct nfp_net *nn, struct sk_buff *skb,
			       enum nfp_ccm_type type,
			       unsigned int reply_size,
			       unsigned int max_reply_size, bool critical)
{
	int err;

	err = nfp_ccm_mbox_msg_prepare(nn, skb, type, reply_size,
				       max_reply_size, GFP_KERNEL);
	if (err)
		goto err_free_skb;

	spin_lock_bh(&nn->mbox_cmsg.queue.lock);

	err = nfp_ccm_mbox_msg_enqueue(nn, skb, type, critical);
	if (err)
		goto err_unlock;

	/* First in queue takes the mailbox lock and processes the batch */
	if (!nfp_ccm_mbox_is_first(nn, skb)) {
		bool to;

		spin_unlock_bh(&nn->mbox_cmsg.queue.lock);

		to = !wait_event_timeout(nn->mbox_cmsg.wq,
					 nfp_ccm_mbox_done(skb) ||
					 nfp_ccm_mbox_should_run(nn, skb),
					 msecs_to_jiffies(NFP_CCM_TIMEOUT));

		/* fast path for those completed by another thread */
		if (nfp_ccm_mbox_done(skb)) {
			smp_rmb(); /* pairs with wmb after data is written */
			return nfp_ccm_mbox_skb_return(skb);
		}

		spin_lock_bh(&nn->mbox_cmsg.queue.lock);

		if (!nfp_ccm_mbox_is_first(nn, skb)) {
			WARN_ON(!to);

			err = nfp_ccm_mbox_unlink_unlock(nn, skb, type);
			if (err)
				goto err_free_skb;
			return 0;
		}
	}

	/* run queue expects the lock held */
	nfp_ccm_mbox_run_queue_unlock(nn);
	return nfp_ccm_mbox_skb_return(skb);

err_unlock:
	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);
err_free_skb:
	dev_kfree_skb_any(skb);
	return err;
}

int nfp_ccm_mbox_communicate(struct nfp_net *nn, struct sk_buff *skb,
			     enum nfp_ccm_type type,
			     unsigned int reply_size,
			     unsigned int max_reply_size)
{
	return __nfp_ccm_mbox_communicate(nn, skb, type, reply_size,
					  max_reply_size, false);
}

static void nfp_ccm_mbox_post_runq_work(struct work_struct *work)
{
	struct sk_buff *skb;
	struct nfp_net *nn;

	nn = container_of(work, struct nfp_net, mbox_cmsg.runq_work);

	spin_lock_bh(&nn->mbox_cmsg.queue.lock);

	skb = __skb_peek(&nn->mbox_cmsg.queue);
	if (WARN_ON(!skb || !nfp_ccm_mbox_is_posted(skb) ||
		    !nfp_ccm_mbox_should_run(nn, skb))) {
		spin_unlock_bh(&nn->mbox_cmsg.queue.lock);
		return;
	}

	nfp_ccm_mbox_run_queue_unlock(nn);
}

static void nfp_ccm_mbox_post_wait_work(struct work_struct *work)
{
	struct sk_buff *skb;
	struct nfp_net *nn;
	int err;

	nn = container_of(work, struct nfp_net, mbox_cmsg.wait_work);

	skb = skb_peek(&nn->mbox_cmsg.queue);
	if (WARN_ON(!skb || !nfp_ccm_mbox_is_posted(skb)))
		/* Should never happen so it's unclear what to do here.. */
		goto exit_unlock_wake;

	err = nfp_net_mbox_reconfig_wait_posted(nn);
	if (!err)
		nfp_ccm_mbox_copy_out(nn, skb);
	else
		nfp_ccm_mbox_mark_all_err(nn, skb, -EIO);
exit_unlock_wake:
	nn_ctrl_bar_unlock(nn);
	wake_up_all(&nn->mbox_cmsg.wq);
}

int nfp_ccm_mbox_post(struct nfp_net *nn, struct sk_buff *skb,
		      enum nfp_ccm_type type, unsigned int max_reply_size)
{
	int err;

	err = nfp_ccm_mbox_msg_prepare(nn, skb, type, 0, max_reply_size,
				       GFP_ATOMIC);
	if (err)
		goto err_free_skb;

	nfp_ccm_mbox_mark_posted(skb);

	spin_lock_bh(&nn->mbox_cmsg.queue.lock);

	err = nfp_ccm_mbox_msg_enqueue(nn, skb, type, false);
	if (err)
		goto err_unlock;

	if (nfp_ccm_mbox_is_first(nn, skb)) {
		if (nn_ctrl_bar_trylock(nn)) {
			nfp_ccm_mbox_copy_in(nn, skb);
			nfp_net_mbox_reconfig_post(nn,
						   NFP_NET_CFG_MBOX_CMD_TLV_CMSG);
			queue_work(nn->mbox_cmsg.workq,
				   &nn->mbox_cmsg.wait_work);
		} else {
			nfp_ccm_mbox_mark_next_runner(nn);
		}
	}

	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);

	return 0;

err_unlock:
	spin_unlock_bh(&nn->mbox_cmsg.queue.lock);
err_free_skb:
	dev_kfree_skb_any(skb);
	return err;
}

struct sk_buff *
nfp_ccm_mbox_msg_alloc(struct nfp_net *nn, unsigned int req_size,
		       unsigned int reply_size, gfp_t flags)
{
	unsigned int max_size;
	struct sk_buff *skb;

	if (!reply_size)
		max_size = nfp_ccm_mbox_max_msg(nn);
	else
		max_size = max(req_size, reply_size);
	max_size = round_up(max_size, 4);

	skb = alloc_skb(max_size, flags);
	if (!skb)
		return NULL;

	skb_put(skb, req_size);

	return skb;
}

bool nfp_ccm_mbox_fits(struct nfp_net *nn, unsigned int size)
{
	return nfp_ccm_mbox_max_msg(nn) >= size;
}

int nfp_ccm_mbox_init(struct nfp_net *nn)
{
	return 0;
}

void nfp_ccm_mbox_clean(struct nfp_net *nn)
{
	drain_workqueue(nn->mbox_cmsg.workq);
}

int nfp_ccm_mbox_alloc(struct nfp_net *nn)
{
	skb_queue_head_init(&nn->mbox_cmsg.queue);
	init_waitqueue_head(&nn->mbox_cmsg.wq);
	INIT_WORK(&nn->mbox_cmsg.wait_work, nfp_ccm_mbox_post_wait_work);
	INIT_WORK(&nn->mbox_cmsg.runq_work, nfp_ccm_mbox_post_runq_work);

	nn->mbox_cmsg.workq = alloc_workqueue("nfp-ccm-mbox", WQ_UNBOUND, 0);
	if (!nn->mbox_cmsg.workq)
		return -ENOMEM;
	return 0;
}

void nfp_ccm_mbox_free(struct nfp_net *nn)
{
	destroy_workqueue(nn->mbox_cmsg.workq);
	WARN_ON(!skb_queue_empty(&nn->mbox_cmsg.queue));
}
