// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020-21 Intel Corporation.
 */

#include "iosm_ipc_protocol.h"
#include "iosm_ipc_protocol_ops.h"

/* Get the next free message element.*/
static union ipc_mem_msg_entry *
ipc_protocol_free_msg_get(struct iosm_protocol *ipc_protocol, int *index)
{
	u32 head = le32_to_cpu(ipc_protocol->p_ap_shm->msg_head);
	u32 new_head = (head + 1) % IPC_MEM_MSG_ENTRIES;
	union ipc_mem_msg_entry *msg;

	if (new_head == le32_to_cpu(ipc_protocol->p_ap_shm->msg_tail)) {
		dev_err(ipc_protocol->dev, "message ring is full");
		return NULL;
	}

	/* Get the pointer to the next free message element,
	 * reset the fields and mark is as invalid.
	 */
	msg = &ipc_protocol->p_ap_shm->msg_ring[head];
	memset(msg, 0, sizeof(*msg));

	/* return index in message ring */
	*index = head;

	return msg;
}

/* Updates the message ring Head pointer */
void ipc_protocol_msg_hp_update(struct iosm_imem *ipc_imem)
{
	struct iosm_protocol *ipc_protocol = ipc_imem->ipc_protocol;
	u32 head = le32_to_cpu(ipc_protocol->p_ap_shm->msg_head);
	u32 new_head = (head + 1) % IPC_MEM_MSG_ENTRIES;

	/* Update head pointer and fire doorbell. */
	ipc_protocol->p_ap_shm->msg_head = cpu_to_le32(new_head);
	ipc_protocol->old_msg_tail =
		le32_to_cpu(ipc_protocol->p_ap_shm->msg_tail);

	ipc_pm_signal_hpda_doorbell(&ipc_protocol->pm, IPC_HP_MR, false);
}

/* Allocate and prepare a OPEN_PIPE message.
 * This also allocates the memory for the new TDR structure and
 * updates the pipe structure referenced in the preparation arguments.
 */
static int ipc_protocol_msg_prepipe_open(struct iosm_protocol *ipc_protocol,
					 union ipc_msg_prep_args *args)
{
	int index;
	union ipc_mem_msg_entry *msg =
		ipc_protocol_free_msg_get(ipc_protocol, &index);
	struct ipc_pipe *pipe = args->pipe_open.pipe;
	struct ipc_protocol_td *tdr;
	struct sk_buff **skbr;

	if (!msg) {
		dev_err(ipc_protocol->dev, "failed to get free message");
		return -EIO;
	}

	/* Allocate the skbuf elements for the skbuf which are on the way.
	 * SKB ring is internal memory allocation for driver. No need to
	 * re-calculate the start and end addresses.
	 */
	skbr = kcalloc(pipe->nr_of_entries, sizeof(*skbr), GFP_ATOMIC);
	if (!skbr)
		return -ENOMEM;

	/* Allocate the transfer descriptors for the pipe. */
	tdr = pci_alloc_consistent(ipc_protocol->pcie->pci,
				   pipe->nr_of_entries * sizeof(*tdr),
				   &pipe->phy_tdr_start);
	if (!tdr) {
		kfree(skbr);
		dev_err(ipc_protocol->dev, "tdr alloc error");
		return -ENOMEM;
	}

	pipe->max_nr_of_queued_entries = pipe->nr_of_entries - 1;
	pipe->nr_of_queued_entries = 0;
	pipe->tdr_start = tdr;
	pipe->skbr_start = skbr;
	pipe->old_tail = 0;

	ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr] = 0;

	msg->open_pipe.type_of_message = IPC_MEM_MSG_OPEN_PIPE;
	msg->open_pipe.pipe_nr = pipe->pipe_nr;
	msg->open_pipe.tdr_addr = cpu_to_le64(pipe->phy_tdr_start);
	msg->open_pipe.tdr_entries = cpu_to_le16(pipe->nr_of_entries);
	msg->open_pipe.accumulation_backoff =
				cpu_to_le32(pipe->accumulation_backoff);
	msg->open_pipe.irq_vector = cpu_to_le32(pipe->irq);

	return index;
}

static int ipc_protocol_msg_prepipe_close(struct iosm_protocol *ipc_protocol,
					  union ipc_msg_prep_args *args)
{
	int index = -1;
	union ipc_mem_msg_entry *msg =
		ipc_protocol_free_msg_get(ipc_protocol, &index);
	struct ipc_pipe *pipe = args->pipe_close.pipe;

	if (!msg)
		return -EIO;

	msg->close_pipe.type_of_message = IPC_MEM_MSG_CLOSE_PIPE;
	msg->close_pipe.pipe_nr = pipe->pipe_nr;

	dev_dbg(ipc_protocol->dev, "IPC_MEM_MSG_CLOSE_PIPE(pipe_nr=%d)",
		msg->close_pipe.pipe_nr);

	return index;
}

static int ipc_protocol_msg_prep_sleep(struct iosm_protocol *ipc_protocol,
				       union ipc_msg_prep_args *args)
{
	int index = -1;
	union ipc_mem_msg_entry *msg =
		ipc_protocol_free_msg_get(ipc_protocol, &index);

	if (!msg) {
		dev_err(ipc_protocol->dev, "failed to get free message");
		return -EIO;
	}

	/* Prepare and send the host sleep message to CP to enter or exit D3. */
	msg->host_sleep.type_of_message = IPC_MEM_MSG_SLEEP;
	msg->host_sleep.target = args->sleep.target; /* 0=host, 1=device */

	/* state; 0=enter, 1=exit 2=enter w/o protocol */
	msg->host_sleep.state = args->sleep.state;

	dev_dbg(ipc_protocol->dev, "IPC_MEM_MSG_SLEEP(target=%d; state=%d)",
		msg->host_sleep.target, msg->host_sleep.state);

	return index;
}

static int ipc_protocol_msg_prep_feature_set(struct iosm_protocol *ipc_protocol,
					     union ipc_msg_prep_args *args)
{
	int index = -1;
	union ipc_mem_msg_entry *msg =
		ipc_protocol_free_msg_get(ipc_protocol, &index);

	if (!msg) {
		dev_err(ipc_protocol->dev, "failed to get free message");
		return -EIO;
	}

	msg->feature_set.type_of_message = IPC_MEM_MSG_FEATURE_SET;
	msg->feature_set.reset_enable = args->feature_set.reset_enable <<
					RESET_BIT;

	dev_dbg(ipc_protocol->dev, "IPC_MEM_MSG_FEATURE_SET(reset_enable=%d)",
		msg->feature_set.reset_enable >> RESET_BIT);

	return index;
}

/* Processes the message consumed by CP. */
bool ipc_protocol_msg_process(struct iosm_imem *ipc_imem, int irq)
{
	struct iosm_protocol *ipc_protocol = ipc_imem->ipc_protocol;
	struct ipc_rsp **rsp_ring = ipc_protocol->rsp_ring;
	bool msg_processed = false;
	u32 i;

	if (le32_to_cpu(ipc_protocol->p_ap_shm->msg_tail) >=
			IPC_MEM_MSG_ENTRIES) {
		dev_err(ipc_protocol->dev, "msg_tail out of range: %d",
			le32_to_cpu(ipc_protocol->p_ap_shm->msg_tail));
		return msg_processed;
	}

	if (irq != IMEM_IRQ_DONT_CARE &&
	    irq != ipc_protocol->p_ap_shm->ci.msg_irq_vector)
		return msg_processed;

	for (i = ipc_protocol->old_msg_tail;
	     i != le32_to_cpu(ipc_protocol->p_ap_shm->msg_tail);
	     i = (i + 1) % IPC_MEM_MSG_ENTRIES) {
		union ipc_mem_msg_entry *msg =
			&ipc_protocol->p_ap_shm->msg_ring[i];

		dev_dbg(ipc_protocol->dev, "msg[%d]: type=%u status=%d", i,
			msg->common.type_of_message,
			msg->common.completion_status);

		/* Update response with status and wake up waiting requestor */
		if (rsp_ring[i]) {
			rsp_ring[i]->status =
				le32_to_cpu(msg->common.completion_status);
			complete(&rsp_ring[i]->completion);
			rsp_ring[i] = NULL;
		}
		msg_processed = true;
	}

	ipc_protocol->old_msg_tail = i;
	return msg_processed;
}

/* Sends data from UL list to CP for the provided pipe by updating the Head
 * pointer of given pipe.
 */
bool ipc_protocol_ul_td_send(struct iosm_protocol *ipc_protocol,
			     struct ipc_pipe *pipe,
			     struct sk_buff_head *p_ul_list)
{
	struct ipc_protocol_td *td;
	bool hpda_pending = false;
	struct sk_buff *skb;
	s32 free_elements;
	u32 head;
	u32 tail;

	if (!ipc_protocol->p_ap_shm) {
		dev_err(ipc_protocol->dev, "driver is not initialized");
		return false;
	}

	/* Get head and tail of the td list and calculate
	 * the number of free elements.
	 */
	head = le32_to_cpu(ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr]);
	tail = pipe->old_tail;

	while (!skb_queue_empty(p_ul_list)) {
		if (head < tail)
			free_elements = tail - head - 1;
		else
			free_elements =
				pipe->nr_of_entries - head + ((s32)tail - 1);

		if (free_elements <= 0) {
			dev_dbg(ipc_protocol->dev,
				"no free td elements for UL pipe %d",
				pipe->pipe_nr);
			break;
		}

		/* Get the td address. */
		td = &pipe->tdr_start[head];

		/* Take the first element of the uplink list and add it
		 * to the td list.
		 */
		skb = skb_dequeue(p_ul_list);
		if (WARN_ON(!skb))
			break;

		/* Save the reference to the uplink skbuf. */
		pipe->skbr_start[head] = skb;

		td->buffer.address = IPC_CB(skb)->mapping;
		td->scs = cpu_to_le32(skb->len) & cpu_to_le32(SIZE_MASK);
		td->next = 0;

		pipe->nr_of_queued_entries++;

		/* Calculate the new head and save it. */
		head++;
		if (head >= pipe->nr_of_entries)
			head = 0;

		ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr] =
			cpu_to_le32(head);
	}

	if (pipe->old_head != head) {
		dev_dbg(ipc_protocol->dev, "New UL TDs Pipe:%d", pipe->pipe_nr);

		pipe->old_head = head;
		/* Trigger doorbell because of pending UL packets. */
		hpda_pending = true;
	}

	return hpda_pending;
}

/* Checks for Tail pointer update from CP and returns the data as SKB. */
struct sk_buff *ipc_protocol_ul_td_process(struct iosm_protocol *ipc_protocol,
					   struct ipc_pipe *pipe)
{
	struct ipc_protocol_td *p_td = &pipe->tdr_start[pipe->old_tail];
	struct sk_buff *skb = pipe->skbr_start[pipe->old_tail];

	pipe->nr_of_queued_entries--;
	pipe->old_tail++;
	if (pipe->old_tail >= pipe->nr_of_entries)
		pipe->old_tail = 0;

	if (!p_td->buffer.address) {
		dev_err(ipc_protocol->dev, "Td buffer address is NULL");
		return NULL;
	}

	if (p_td->buffer.address != IPC_CB(skb)->mapping) {
		dev_err(ipc_protocol->dev,
			"pipe %d: invalid buf_addr or skb_data",
			pipe->pipe_nr);
		return NULL;
	}

	return skb;
}

/* Allocates an SKB for CP to send data and updates the Head Pointer
 * of the given Pipe#.
 */
bool ipc_protocol_dl_td_prepare(struct iosm_protocol *ipc_protocol,
				struct ipc_pipe *pipe)
{
	struct ipc_protocol_td *td;
	dma_addr_t mapping = 0;
	u32 head, new_head;
	struct sk_buff *skb;
	u32 tail;

	/* Get head and tail of the td list and calculate
	 * the number of free elements.
	 */
	head = le32_to_cpu(ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr]);
	tail = le32_to_cpu(ipc_protocol->p_ap_shm->tail_array[pipe->pipe_nr]);

	new_head = head + 1;
	if (new_head >= pipe->nr_of_entries)
		new_head = 0;

	if (new_head == tail)
		return false;

	/* Get the td address. */
	td = &pipe->tdr_start[head];

	/* Allocate the skbuf for the descriptor. */
	skb = ipc_pcie_alloc_skb(ipc_protocol->pcie, pipe->buf_size, GFP_ATOMIC,
				 &mapping, DMA_FROM_DEVICE,
				 IPC_MEM_DL_ETH_OFFSET);
	if (!skb)
		return false;

	td->buffer.address = mapping;
	td->scs = cpu_to_le32(pipe->buf_size) & cpu_to_le32(SIZE_MASK);
	td->next = 0;

	/* store the new head value. */
	ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr] =
		cpu_to_le32(new_head);

	/* Save the reference to the skbuf. */
	pipe->skbr_start[head] = skb;

	pipe->nr_of_queued_entries++;

	return true;
}

/* Processes DL TD's */
struct sk_buff *ipc_protocol_dl_td_process(struct iosm_protocol *ipc_protocol,
					   struct ipc_pipe *pipe)
{
	u32 tail =
		le32_to_cpu(ipc_protocol->p_ap_shm->tail_array[pipe->pipe_nr]);
	struct ipc_protocol_td *p_td;
	struct sk_buff *skb;

	if (!pipe->tdr_start)
		return NULL;

	/* Copy the reference to the downlink buffer. */
	p_td = &pipe->tdr_start[pipe->old_tail];
	skb = pipe->skbr_start[pipe->old_tail];

	/* Reset the ring elements. */
	pipe->skbr_start[pipe->old_tail] = NULL;

	pipe->nr_of_queued_entries--;

	pipe->old_tail++;
	if (pipe->old_tail >= pipe->nr_of_entries)
		pipe->old_tail = 0;

	if (!skb) {
		dev_err(ipc_protocol->dev, "skb is null");
		goto ret;
	} else if (!p_td->buffer.address) {
		dev_err(ipc_protocol->dev, "td/buffer address is null");
		ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);
		skb = NULL;
		goto ret;
	}

	if (!IPC_CB(skb)) {
		dev_err(ipc_protocol->dev, "pipe# %d, tail: %d skb_cb is NULL",
			pipe->pipe_nr, tail);
		ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);
		skb = NULL;
		goto ret;
	}

	if (p_td->buffer.address != IPC_CB(skb)->mapping) {
		dev_err(ipc_protocol->dev, "invalid buf=%p or skb=%p",
			(void *)p_td->buffer.address, skb->data);
		ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);
		skb = NULL;
		goto ret;
	} else if ((le32_to_cpu(p_td->scs) & SIZE_MASK) > pipe->buf_size) {
		dev_err(ipc_protocol->dev, "invalid buffer size %d > %d",
			le32_to_cpu(p_td->scs) & SIZE_MASK,
			pipe->buf_size);
		ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);
		skb = NULL;
		goto ret;
	} else if (le32_to_cpu(p_td->scs) >> COMPLETION_STATUS ==
		  IPC_MEM_TD_CS_ABORT) {
		/* Discard aborted buffers. */
		dev_dbg(ipc_protocol->dev, "discard 'aborted' buffers");
		ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);
		skb = NULL;
		goto ret;
	}

	/* Set the length field in skbuf. */
	skb_put(skb, le32_to_cpu(p_td->scs) & SIZE_MASK);

ret:
	return skb;
}

void ipc_protocol_get_head_tail_index(struct iosm_protocol *ipc_protocol,
				      struct ipc_pipe *pipe, u32 *head,
				      u32 *tail)
{
	struct ipc_protocol_ap_shm *ipc_ap_shm = ipc_protocol->p_ap_shm;

	if (head)
		*head = le32_to_cpu(ipc_ap_shm->head_array[pipe->pipe_nr]);

	if (tail)
		*tail = le32_to_cpu(ipc_ap_shm->tail_array[pipe->pipe_nr]);
}

/* Frees the TDs given to CP.  */
void ipc_protocol_pipe_cleanup(struct iosm_protocol *ipc_protocol,
			       struct ipc_pipe *pipe)
{
	struct sk_buff *skb;
	u32 head;
	u32 tail;

	/* Get the start and the end of the buffer list. */
	head = le32_to_cpu(ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr]);
	tail = pipe->old_tail;

	/* Reset tail and head to 0. */
	ipc_protocol->p_ap_shm->tail_array[pipe->pipe_nr] = 0;
	ipc_protocol->p_ap_shm->head_array[pipe->pipe_nr] = 0;

	/* Free pending uplink and downlink buffers. */
	if (pipe->skbr_start) {
		while (head != tail) {
			/* Get the reference to the skbuf,
			 * which is on the way and free it.
			 */
			skb = pipe->skbr_start[tail];
			if (skb)
				ipc_pcie_kfree_skb(ipc_protocol->pcie, skb);

			tail++;
			if (tail >= pipe->nr_of_entries)
				tail = 0;
		}

		kfree(pipe->skbr_start);
		pipe->skbr_start = NULL;
	}

	pipe->old_tail = 0;

	/* Free and reset the td and skbuf circular buffers. kfree is save! */
	if (pipe->tdr_start) {
		pci_free_consistent(ipc_protocol->pcie->pci,
				    sizeof(*pipe->tdr_start) *
					    pipe->nr_of_entries,
				    pipe->tdr_start, pipe->phy_tdr_start);

		pipe->tdr_start = NULL;
	}
}

enum ipc_mem_device_ipc_state ipc_protocol_get_ipc_status(struct iosm_protocol
							  *ipc_protocol)
{
	return (enum ipc_mem_device_ipc_state)
		le32_to_cpu(ipc_protocol->p_ap_shm->device_info.ipc_status);
}

enum ipc_mem_exec_stage
ipc_protocol_get_ap_exec_stage(struct iosm_protocol *ipc_protocol)
{
	return le32_to_cpu(ipc_protocol->p_ap_shm->device_info.execution_stage);
}

int ipc_protocol_msg_prep(struct iosm_imem *ipc_imem,
			  enum ipc_msg_prep_type msg_type,
			  union ipc_msg_prep_args *args)
{
	struct iosm_protocol *ipc_protocol = ipc_imem->ipc_protocol;

	switch (msg_type) {
	case IPC_MSG_PREP_SLEEP:
		return ipc_protocol_msg_prep_sleep(ipc_protocol, args);

	case IPC_MSG_PREP_PIPE_OPEN:
		return ipc_protocol_msg_prepipe_open(ipc_protocol, args);

	case IPC_MSG_PREP_PIPE_CLOSE:
		return ipc_protocol_msg_prepipe_close(ipc_protocol, args);

	case IPC_MSG_PREP_FEATURE_SET:
		return ipc_protocol_msg_prep_feature_set(ipc_protocol, args);

		/* Unsupported messages in protocol */
	case IPC_MSG_PREP_MAP:
	case IPC_MSG_PREP_UNMAP:
	default:
		dev_err(ipc_protocol->dev,
			"unsupported message type: %d in protocol", msg_type);
		return -EINVAL;
	}
}

u32
ipc_protocol_pm_dev_get_sleep_notification(struct iosm_protocol *ipc_protocol)
{
	struct ipc_protocol_ap_shm *ipc_ap_shm = ipc_protocol->p_ap_shm;

	return le32_to_cpu(ipc_ap_shm->device_info.device_sleep_notification);
}
