/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2015 Intel Corporation.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * Intel SCIF driver.
 *
 */

#include "scif_main.h"

/**
 * scif_recv_mark: Handle SCIF_MARK request
 * @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.
 * @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
 * @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.
 * @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
 * @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
 * @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.
 * @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_status *status = arg;

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

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;
	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) {
		tx->callback = scif_prog_signal_cb;
		tx->callback_param = status;
	}
	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));
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
 * 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);
