// SPDX-License-Identifier: GPL-2.0-only
/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2015 Intel Corporation.
 *
 * Intel SCIF driver.
 */

#include "scif_main.h"

/**
 * scif_recv_mark: Handle SCIF_MARK request
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has requested a mark.
 */
void scif_recv_mark(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	int mark = 0;
	int err;

	err = _scif_fence_mark(ep, &mark);
	if (err)
		msg->uop = SCIF_MARK_NACK;
	else
		msg->uop = SCIF_MARK_ACK;
	msg->payload[0] = ep->remote_ep;
	msg->payload[2] = mark;
	scif_nodeqp_send(ep->remote_dev, msg);
}

/**
 * scif_recv_mark_resp: Handle SCIF_MARK_(N)ACK messages.
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has responded to a SCIF_MARK message.
 */
void scif_recv_mark_resp(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	struct scif_fence_info *fence_req =
		(struct scif_fence_info *)msg->payload[1];

	mutex_lock(&ep->rma_info.rma_lock);
	if (msg->uop == SCIF_MARK_ACK) {
		fence_req->state = OP_COMPLETED;
		fence_req->dma_mark = (int)msg->payload[2];
	} else {
		fence_req->state = OP_FAILED;
	}
	mutex_unlock(&ep->rma_info.rma_lock);
	complete(&fence_req->comp);
}

/**
 * scif_recv_wait: Handle SCIF_WAIT request
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has requested waiting on a fence.
 */
void scif_recv_wait(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	struct scif_remote_fence_info *fence;

	/*
	 * Allocate structure for remote fence information and
	 * send a NACK if the allocation failed. The peer will
	 * return ENOMEM upon receiving a NACK.
	 */
	fence = kmalloc(sizeof(*fence), GFP_KERNEL);
	if (!fence) {
		msg->payload[0] = ep->remote_ep;
		msg->uop = SCIF_WAIT_NACK;
		scif_nodeqp_send(ep->remote_dev, msg);
		return;
	}

	/* Prepare the fence request */
	memcpy(&fence->msg, msg, sizeof(struct scifmsg));
	INIT_LIST_HEAD(&fence->list);

	/* Insert to the global remote fence request list */
	mutex_lock(&scif_info.fencelock);
	atomic_inc(&ep->rma_info.fence_refcount);
	list_add_tail(&fence->list, &scif_info.fence);
	mutex_unlock(&scif_info.fencelock);

	schedule_work(&scif_info.misc_work);
}

/**
 * scif_recv_wait_resp: Handle SCIF_WAIT_(N)ACK messages.
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has responded to a SCIF_WAIT message.
 */
void scif_recv_wait_resp(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	struct scif_fence_info *fence_req =
		(struct scif_fence_info *)msg->payload[1];

	mutex_lock(&ep->rma_info.rma_lock);
	if (msg->uop == SCIF_WAIT_ACK)
		fence_req->state = OP_COMPLETED;
	else
		fence_req->state = OP_FAILED;
	mutex_unlock(&ep->rma_info.rma_lock);
	complete(&fence_req->comp);
}

/**
 * scif_recv_sig_local: Handle SCIF_SIG_LOCAL request
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has requested a signal on a local offset.
 */
void scif_recv_sig_local(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	int err;

	err = scif_prog_signal(ep, msg->payload[1], msg->payload[2],
			       SCIF_WINDOW_SELF);
	if (err)
		msg->uop = SCIF_SIG_NACK;
	else
		msg->uop = SCIF_SIG_ACK;
	msg->payload[0] = ep->remote_ep;
	scif_nodeqp_send(ep->remote_dev, msg);
}

/**
 * scif_recv_sig_remote: Handle SCIF_SIGNAL_REMOTE request
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has requested a signal on a remote offset.
 */
void scif_recv_sig_remote(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	int err;

	err = scif_prog_signal(ep, msg->payload[1], msg->payload[2],
			       SCIF_WINDOW_PEER);
	if (err)
		msg->uop = SCIF_SIG_NACK;
	else
		msg->uop = SCIF_SIG_ACK;
	msg->payload[0] = ep->remote_ep;
	scif_nodeqp_send(ep->remote_dev, msg);
}

/**
 * scif_recv_sig_resp: Handle SCIF_SIG_(N)ACK messages.
 * @scifdev:	SCIF device
 * @msg:	Interrupt message
 *
 * The peer has responded to a signal request.
 */
void scif_recv_sig_resp(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	struct scif_fence_info *fence_req =
		(struct scif_fence_info *)msg->payload[3];

	mutex_lock(&ep->rma_info.rma_lock);
	if (msg->uop == SCIF_SIG_ACK)
		fence_req->state = OP_COMPLETED;
	else
		fence_req->state = OP_FAILED;
	mutex_unlock(&ep->rma_info.rma_lock);
	complete(&fence_req->comp);
}

static inline void *scif_get_local_va(off_t off, struct scif_window *window)
{
	struct page **pages = window->pinned_pages->pages;
	int page_nr = (off - window->offset) >> PAGE_SHIFT;
	off_t page_off = off & ~PAGE_MASK;

	return page_address(pages[page_nr]) + page_off;
}

static void scif_prog_signal_cb(void *arg)
{
	struct scif_cb_arg *cb_arg = arg;

	dma_pool_free(cb_arg->ep->remote_dev->signal_pool, cb_arg->status,
		      cb_arg->src_dma_addr);
	kfree(cb_arg);
}

static int _scif_prog_signal(scif_epd_t epd, dma_addr_t dst, u64 val)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	struct dma_chan *chan = ep->rma_info.dma_chan;
	struct dma_device *ddev = chan->device;
	bool x100 = !is_dma_copy_aligned(chan->device, 1, 1, 1);
	struct dma_async_tx_descriptor *tx;
	struct scif_status *status = NULL;
	struct scif_cb_arg *cb_arg = NULL;
	dma_addr_t src;
	dma_cookie_t cookie;
	int err;

	tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE);
	if (!tx) {
		err = -ENOMEM;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto alloc_fail;
	}
	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		err = (int)cookie;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto alloc_fail;
	}
	dma_async_issue_pending(chan);
	if (x100) {
		/*
		 * For X100 use the status descriptor to write the value to
		 * the destination.
		 */
		tx = ddev->device_prep_dma_imm_data(chan, dst, val, 0);
	} else {
		status = dma_pool_alloc(ep->remote_dev->signal_pool, GFP_KERNEL,
					&src);
		if (!status) {
			err = -ENOMEM;
			dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
				__func__, __LINE__, err);
			goto alloc_fail;
		}
		status->val = val;
		status->src_dma_addr = src;
		status->ep = ep;
		src += offsetof(struct scif_status, val);
		tx = ddev->device_prep_dma_memcpy(chan, dst, src, sizeof(val),
						  DMA_PREP_INTERRUPT);
	}
	if (!tx) {
		err = -ENOMEM;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto dma_fail;
	}
	if (!x100) {
		cb_arg = kmalloc(sizeof(*cb_arg), GFP_KERNEL);
		if (!cb_arg) {
			err = -ENOMEM;
			goto dma_fail;
		}
		cb_arg->src_dma_addr = src;
		cb_arg->status = status;
		cb_arg->ep = ep;
		tx->callback = scif_prog_signal_cb;
		tx->callback_param = cb_arg;
	}
	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		err = -EIO;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto dma_fail;
	}
	dma_async_issue_pending(chan);
	return 0;
dma_fail:
	if (!x100) {
		dma_pool_free(ep->remote_dev->signal_pool, status,
			      src - offsetof(struct scif_status, val));
		kfree(cb_arg);
	}
alloc_fail:
	return err;
}

/**
 * scif_prog_signal:
 * @epd: Endpoint Descriptor
 * @offset: registered address to write @val to
 * @val: Value to be written at @offset
 * @type: Type of the window.
 *
 * Arrange to write a value to the registered offset after ensuring that the
 * offset provided is indeed valid.
 */
int scif_prog_signal(scif_epd_t epd, off_t offset, u64 val,
		     enum scif_window_type type)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	struct scif_window *window = NULL;
	struct scif_rma_req req;
	dma_addr_t dst_dma_addr;
	int err;

	mutex_lock(&ep->rma_info.rma_lock);
	req.out_window = &window;
	req.offset = offset;
	req.nr_bytes = sizeof(u64);
	req.prot = SCIF_PROT_WRITE;
	req.type = SCIF_WINDOW_SINGLE;
	if (type == SCIF_WINDOW_SELF)
		req.head = &ep->rma_info.reg_list;
	else
		req.head = &ep->rma_info.remote_reg_list;
	/* Does a valid window exist? */
	err = scif_query_window(&req);
	if (err) {
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto unlock_ret;
	}

	if (scif_is_mgmt_node() && scifdev_self(ep->remote_dev)) {
		u64 *dst_virt;

		if (type == SCIF_WINDOW_SELF)
			dst_virt = scif_get_local_va(offset, window);
		else
			dst_virt =
			scif_get_local_va(offset, (struct scif_window *)
					  window->peer_window);
		*dst_virt = val;
	} else {
		dst_dma_addr = __scif_off_to_dma_addr(window, offset);
		err = _scif_prog_signal(epd, dst_dma_addr, val);
	}
unlock_ret:
	mutex_unlock(&ep->rma_info.rma_lock);
	return err;
}

static int _scif_fence_wait(scif_epd_t epd, int mark)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	dma_cookie_t cookie = mark & ~SCIF_REMOTE_FENCE;
	int err;

	/* Wait for DMA callback in scif_fence_mark_cb(..) */
	err = wait_event_interruptible_timeout(ep->rma_info.markwq,
					       dma_async_is_tx_complete(
					       ep->rma_info.dma_chan,
					       cookie, NULL, NULL) ==
					       DMA_COMPLETE,
					       SCIF_NODE_ALIVE_TIMEOUT);
	if (!err)
		err = -ETIMEDOUT;
	else if (err > 0)
		err = 0;
	return err;
}

/**
 * scif_rma_handle_remote_fences:
 *
 * This routine services remote fence requests.
 */
void scif_rma_handle_remote_fences(void)
{
	struct list_head *item, *tmp;
	struct scif_remote_fence_info *fence;
	struct scif_endpt *ep;
	int mark, err;

	might_sleep();
	mutex_lock(&scif_info.fencelock);
	list_for_each_safe(item, tmp, &scif_info.fence) {
		fence = list_entry(item, struct scif_remote_fence_info,
				   list);
		/* Remove fence from global list */
		list_del(&fence->list);

		/* Initiate the fence operation */
		ep = (struct scif_endpt *)fence->msg.payload[0];
		mark = fence->msg.payload[2];
		err = _scif_fence_wait(ep, mark);
		if (err)
			fence->msg.uop = SCIF_WAIT_NACK;
		else
			fence->msg.uop = SCIF_WAIT_ACK;
		fence->msg.payload[0] = ep->remote_ep;
		scif_nodeqp_send(ep->remote_dev, &fence->msg);
		kfree(fence);
		if (!atomic_sub_return(1, &ep->rma_info.fence_refcount))
			schedule_work(&scif_info.misc_work);
	}
	mutex_unlock(&scif_info.fencelock);
}

static int _scif_send_fence(scif_epd_t epd, int uop, int mark, int *out_mark)
{
	int err;
	struct scifmsg msg;
	struct scif_fence_info *fence_req;
	struct scif_endpt *ep = (struct scif_endpt *)epd;

	fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL);
	if (!fence_req) {
		err = -ENOMEM;
		goto error;
	}

	fence_req->state = OP_IN_PROGRESS;
	init_completion(&fence_req->comp);

	msg.src = ep->port;
	msg.uop = uop;
	msg.payload[0] = ep->remote_ep;
	msg.payload[1] = (u64)fence_req;
	if (uop == SCIF_WAIT)
		msg.payload[2] = mark;
	spin_lock(&ep->lock);
	if (ep->state == SCIFEP_CONNECTED)
		err = scif_nodeqp_send(ep->remote_dev, &msg);
	else
		err = -ENOTCONN;
	spin_unlock(&ep->lock);
	if (err)
		goto error_free;
retry:
	/* Wait for a SCIF_WAIT_(N)ACK message */
	err = wait_for_completion_timeout(&fence_req->comp,
					  SCIF_NODE_ALIVE_TIMEOUT);
	if (!err && scifdev_alive(ep))
		goto retry;
	if (!err)
		err = -ENODEV;
	if (err > 0)
		err = 0;
	mutex_lock(&ep->rma_info.rma_lock);
	if (err < 0) {
		if (fence_req->state == OP_IN_PROGRESS)
			fence_req->state = OP_FAILED;
	}
	if (fence_req->state == OP_FAILED && !err)
		err = -ENOMEM;
	if (uop == SCIF_MARK && fence_req->state == OP_COMPLETED)
		*out_mark = SCIF_REMOTE_FENCE | fence_req->dma_mark;
	mutex_unlock(&ep->rma_info.rma_lock);
error_free:
	kfree(fence_req);
error:
	return err;
}

/**
 * scif_send_fence_mark:
 * @epd: end point descriptor.
 * @out_mark: Output DMA mark reported by peer.
 *
 * Send a remote fence mark request.
 */
static int scif_send_fence_mark(scif_epd_t epd, int *out_mark)
{
	return _scif_send_fence(epd, SCIF_MARK, 0, out_mark);
}

/**
 * scif_send_fence_wait:
 * @epd: end point descriptor.
 * @mark: DMA mark to wait for.
 *
 * Send a remote fence wait request.
 */
static int scif_send_fence_wait(scif_epd_t epd, int mark)
{
	return _scif_send_fence(epd, SCIF_WAIT, mark, NULL);
}

static int _scif_send_fence_signal_wait(struct scif_endpt *ep,
					struct scif_fence_info *fence_req)
{
	int err;

retry:
	/* Wait for a SCIF_SIG_(N)ACK message */
	err = wait_for_completion_timeout(&fence_req->comp,
					  SCIF_NODE_ALIVE_TIMEOUT);
	if (!err && scifdev_alive(ep))
		goto retry;
	if (!err)
		err = -ENODEV;
	if (err > 0)
		err = 0;
	if (err < 0) {
		mutex_lock(&ep->rma_info.rma_lock);
		if (fence_req->state == OP_IN_PROGRESS)
			fence_req->state = OP_FAILED;
		mutex_unlock(&ep->rma_info.rma_lock);
	}
	if (fence_req->state == OP_FAILED && !err)
		err = -ENXIO;
	return err;
}

/**
 * scif_send_fence_signal:
 * @epd: endpoint descriptor
 * @loff: local offset
 * @lval: local value to write to loffset
 * @roff: remote offset
 * @rval: remote value to write to roffset
 * @flags: flags
 *
 * Sends a remote fence signal request
 */
static int scif_send_fence_signal(scif_epd_t epd, off_t roff, u64 rval,
				  off_t loff, u64 lval, int flags)
{
	int err = 0;
	struct scifmsg msg;
	struct scif_fence_info *fence_req;
	struct scif_endpt *ep = (struct scif_endpt *)epd;

	fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL);
	if (!fence_req) {
		err = -ENOMEM;
		goto error;
	}

	fence_req->state = OP_IN_PROGRESS;
	init_completion(&fence_req->comp);
	msg.src = ep->port;
	if (flags & SCIF_SIGNAL_LOCAL) {
		msg.uop = SCIF_SIG_LOCAL;
		msg.payload[0] = ep->remote_ep;
		msg.payload[1] = roff;
		msg.payload[2] = rval;
		msg.payload[3] = (u64)fence_req;
		spin_lock(&ep->lock);
		if (ep->state == SCIFEP_CONNECTED)
			err = scif_nodeqp_send(ep->remote_dev, &msg);
		else
			err = -ENOTCONN;
		spin_unlock(&ep->lock);
		if (err)
			goto error_free;
		err = _scif_send_fence_signal_wait(ep, fence_req);
		if (err)
			goto error_free;
	}
	fence_req->state = OP_IN_PROGRESS;

	if (flags & SCIF_SIGNAL_REMOTE) {
		msg.uop = SCIF_SIG_REMOTE;
		msg.payload[0] = ep->remote_ep;
		msg.payload[1] = loff;
		msg.payload[2] = lval;
		msg.payload[3] = (u64)fence_req;
		spin_lock(&ep->lock);
		if (ep->state == SCIFEP_CONNECTED)
			err = scif_nodeqp_send(ep->remote_dev, &msg);
		else
			err = -ENOTCONN;
		spin_unlock(&ep->lock);
		if (err)
			goto error_free;
		err = _scif_send_fence_signal_wait(ep, fence_req);
	}
error_free:
	kfree(fence_req);
error:
	return err;
}

static void scif_fence_mark_cb(void *arg)
{
	struct scif_endpt *ep = (struct scif_endpt *)arg;

	wake_up_interruptible(&ep->rma_info.markwq);
	atomic_dec(&ep->rma_info.fence_refcount);
}

/**
 * _scif_fence_mark:
 * @epd: endpoint descriptor
 * @mark: DMA mark to set-up
 *
 * Set up a mark for this endpoint and return the value of the mark.
 */
int _scif_fence_mark(scif_epd_t epd, int *mark)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	struct dma_chan *chan = ep->rma_info.dma_chan;
	struct dma_device *ddev = chan->device;
	struct dma_async_tx_descriptor *tx;
	dma_cookie_t cookie;
	int err;

	tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE);
	if (!tx) {
		err = -ENOMEM;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		err = (int)cookie;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	dma_async_issue_pending(chan);
	tx = ddev->device_prep_dma_interrupt(chan, DMA_PREP_INTERRUPT);
	if (!tx) {
		err = -ENOMEM;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	tx->callback = scif_fence_mark_cb;
	tx->callback_param = ep;
	*mark = cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		err = (int)cookie;
		dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	atomic_inc(&ep->rma_info.fence_refcount);
	dma_async_issue_pending(chan);
	return 0;
}

#define SCIF_LOOPB_MAGIC_MARK 0xdead

int scif_fence_mark(scif_epd_t epd, int flags, int *mark)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	int err = 0;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x\n",
		ep, flags, *mark);
	err = scif_verify_epd(ep);
	if (err)
		return err;

	/* Invalid flags? */
	if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER))
		return -EINVAL;

	/* At least one of init self or peer RMA should be set */
	if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER)))
		return -EINVAL;

	/* Exactly one of init self or peer RMA should be set but not both */
	if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER))
		return -EINVAL;

	/*
	 * Management node loopback does not need to use DMA.
	 * Return a valid mark to be symmetric.
	 */
	if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) {
		*mark = SCIF_LOOPB_MAGIC_MARK;
		return 0;
	}

	if (flags & SCIF_FENCE_INIT_SELF)
		err = _scif_fence_mark(epd, mark);
	else
		err = scif_send_fence_mark(ep, mark);

	if (err)
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d\n", __func__, __LINE__, err);
	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x err %d\n",
		ep, flags, *mark, err);
	return err;
}
EXPORT_SYMBOL_GPL(scif_fence_mark);

int scif_fence_wait(scif_epd_t epd, int mark)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	int err = 0;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI fence_wait: ep %p mark 0x%x\n",
		ep, mark);
	err = scif_verify_epd(ep);
	if (err)
		return err;
	/*
	 * Management node loopback does not need to use DMA.
	 * The only valid mark provided is 0 so simply
	 * return success if the mark is valid.
	 */
	if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) {
		if (mark == SCIF_LOOPB_MAGIC_MARK)
			return 0;
		else
			return -EINVAL;
	}
	if (mark & SCIF_REMOTE_FENCE)
		err = scif_send_fence_wait(epd, mark);
	else
		err = _scif_fence_wait(epd, mark);
	if (err < 0)
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d\n", __func__, __LINE__, err);
	return err;
}
EXPORT_SYMBOL_GPL(scif_fence_wait);

int scif_fence_signal(scif_epd_t epd, off_t loff, u64 lval,
		      off_t roff, u64 rval, int flags)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	int err = 0;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI fence_signal: ep %p loff 0x%lx lval 0x%llx roff 0x%lx rval 0x%llx flags 0x%x\n",
		ep, loff, lval, roff, rval, flags);
	err = scif_verify_epd(ep);
	if (err)
		return err;

	/* Invalid flags? */
	if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER |
			SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE))
		return -EINVAL;

	/* At least one of init self or peer RMA should be set */
	if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER)))
		return -EINVAL;

	/* Exactly one of init self or peer RMA should be set but not both */
	if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER))
		return -EINVAL;

	/* At least one of SCIF_SIGNAL_LOCAL or SCIF_SIGNAL_REMOTE required */
	if (!(flags & (SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE)))
		return -EINVAL;

	/* Only Dword offsets allowed */
	if ((flags & SCIF_SIGNAL_LOCAL) && (loff & (sizeof(u32) - 1)))
		return -EINVAL;

	/* Only Dword aligned offsets allowed */
	if ((flags & SCIF_SIGNAL_REMOTE) && (roff & (sizeof(u32) - 1)))
		return -EINVAL;

	if (flags & SCIF_FENCE_INIT_PEER) {
		err = scif_send_fence_signal(epd, roff, rval, loff,
					     lval, flags);
	} else {
		/* Local Signal in Local RAS */
		if (flags & SCIF_SIGNAL_LOCAL) {
			err = scif_prog_signal(epd, loff, lval,
					       SCIF_WINDOW_SELF);
			if (err)
				goto error_ret;
		}

		/* Signal in Remote RAS */
		if (flags & SCIF_SIGNAL_REMOTE)
			err = scif_prog_signal(epd, roff,
					       rval, SCIF_WINDOW_PEER);
	}
error_ret:
	if (err)
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d\n", __func__, __LINE__, err);
	return err;
}
EXPORT_SYMBOL_GPL(scif_fence_signal);
