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

#include "iosm_ipc_mux_codec.h"

/* At the begin of the runtime phase the IP MUX channel shall created. */
static int ipc_mux_channel_create(struct iosm_mux *ipc_mux)
{
	int channel_id;

	channel_id = ipc_imem_channel_alloc(ipc_mux->imem, ipc_mux->instance_id,
					    IPC_CTYPE_WWAN);

	if (channel_id < 0) {
		dev_err(ipc_mux->dev,
			"allocation of the MUX channel id failed");
		ipc_mux->state = MUX_S_ERROR;
		ipc_mux->event = MUX_E_NOT_APPLICABLE;
		goto no_channel;
	}

	/* Establish the MUX channel in blocking mode. */
	ipc_mux->channel = ipc_imem_channel_open(ipc_mux->imem, channel_id,
						 IPC_HP_NET_CHANNEL_INIT);

	if (!ipc_mux->channel) {
		dev_err(ipc_mux->dev, "ipc_imem_channel_open failed");
		ipc_mux->state = MUX_S_ERROR;
		ipc_mux->event = MUX_E_NOT_APPLICABLE;
		return -ENODEV; /* MUX channel is not available. */
	}

	/* Define the MUX active state properties. */
	ipc_mux->state = MUX_S_ACTIVE;
	ipc_mux->event = MUX_E_NO_ORDERS;

no_channel:
	return channel_id;
}

/* Reset the session/if id state. */
static void ipc_mux_session_free(struct iosm_mux *ipc_mux, int if_id)
{
	struct mux_session *if_entry;

	if_entry = &ipc_mux->session[if_id];
	/* Reset the session state. */
	if_entry->wwan = NULL;
}

/* Create and send the session open command. */
static struct mux_cmd_open_session_resp *
ipc_mux_session_open_send(struct iosm_mux *ipc_mux, int if_id)
{
	struct mux_cmd_open_session_resp *open_session_resp;
	struct mux_acb *acb = &ipc_mux->acb;
	union mux_cmd_param param;

	/* open_session commands to one ACB and start transmission. */
	param.open_session.flow_ctrl = 0;
	param.open_session.ipv4v6_hints = 0;
	param.open_session.reserved2 = 0;
	param.open_session.dl_head_pad_len = cpu_to_le32(IPC_MEM_DL_ETH_OFFSET);

	/* Finish and transfer ACB. The user thread is suspended.
	 * It is a blocking function call, until CP responds or timeout.
	 */
	acb->wanted_response = MUX_CMD_OPEN_SESSION_RESP;
	if (ipc_mux_dl_acb_send_cmds(ipc_mux, MUX_CMD_OPEN_SESSION, if_id, 0,
				     &param, sizeof(param.open_session), true,
				 false) ||
	    acb->got_response != MUX_CMD_OPEN_SESSION_RESP) {
		dev_err(ipc_mux->dev, "if_id %d: OPEN_SESSION send failed",
			if_id);
		return NULL;
	}

	open_session_resp = &ipc_mux->acb.got_param.open_session_resp;
	if (open_session_resp->response != cpu_to_le32(MUX_CMD_RESP_SUCCESS)) {
		dev_err(ipc_mux->dev,
			"if_id %d,session open failed,response=%d", if_id,
			open_session_resp->response);
		return NULL;
	}

	return open_session_resp;
}

/* Open the first IP session. */
static bool ipc_mux_session_open(struct iosm_mux *ipc_mux,
				 struct mux_session_open *session_open)
{
	struct mux_cmd_open_session_resp *open_session_resp;
	int if_id;

	/* Search for a free session interface id. */
	if_id = le32_to_cpu(session_open->if_id);
	if (if_id < 0 || if_id >= ipc_mux->nr_sessions) {
		dev_err(ipc_mux->dev, "invalid interface id=%d", if_id);
		return false;
	}

	/* Create and send the session open command.
	 * It is a blocking function call, until CP responds or timeout.
	 */
	open_session_resp = ipc_mux_session_open_send(ipc_mux, if_id);
	if (!open_session_resp) {
		ipc_mux_session_free(ipc_mux, if_id);
		session_open->if_id = cpu_to_le32(-1);
		return false;
	}

	/* Initialize the uplink skb accumulator. */
	skb_queue_head_init(&ipc_mux->session[if_id].ul_list);

	ipc_mux->session[if_id].dl_head_pad_len = IPC_MEM_DL_ETH_OFFSET;
	ipc_mux->session[if_id].ul_head_pad_len =
		le32_to_cpu(open_session_resp->ul_head_pad_len);
	ipc_mux->session[if_id].wwan = ipc_mux->wwan;

	/* Reset the flow ctrl stats of the session */
	ipc_mux->session[if_id].flow_ctl_en_cnt = 0;
	ipc_mux->session[if_id].flow_ctl_dis_cnt = 0;
	ipc_mux->session[if_id].ul_flow_credits = 0;
	ipc_mux->session[if_id].net_tx_stop = false;
	ipc_mux->session[if_id].flow_ctl_mask = 0;

	/* Save and return the assigned if id. */
	session_open->if_id = cpu_to_le32(if_id);

	return true;
}

/* Free pending session UL packet. */
static void ipc_mux_session_reset(struct iosm_mux *ipc_mux, int if_id)
{
	/* Reset the session/if id state. */
	ipc_mux_session_free(ipc_mux, if_id);

	/* Empty the uplink skb accumulator. */
	skb_queue_purge(&ipc_mux->session[if_id].ul_list);
}

static void ipc_mux_session_close(struct iosm_mux *ipc_mux,
				  struct mux_session_close *msg)
{
	int if_id;

	/* Copy the session interface id. */
	if_id = le32_to_cpu(msg->if_id);

	if (if_id < 0 || if_id >= ipc_mux->nr_sessions) {
		dev_err(ipc_mux->dev, "invalid session id %d", if_id);
		return;
	}

	/* Create and send the session close command.
	 * It is a blocking function call, until CP responds or timeout.
	 */
	if (ipc_mux_dl_acb_send_cmds(ipc_mux, MUX_CMD_CLOSE_SESSION, if_id, 0,
				     NULL, 0, true, false))
		dev_err(ipc_mux->dev, "if_id %d: CLOSE_SESSION send failed",
			if_id);

	/* Reset the flow ctrl stats of the session */
	ipc_mux->session[if_id].flow_ctl_en_cnt = 0;
	ipc_mux->session[if_id].flow_ctl_dis_cnt = 0;
	ipc_mux->session[if_id].flow_ctl_mask = 0;

	ipc_mux_session_reset(ipc_mux, if_id);
}

static void ipc_mux_channel_close(struct iosm_mux *ipc_mux,
				  struct mux_channel_close *channel_close_p)
{
	int i;

	/* Free pending session UL packet. */
	for (i = 0; i < ipc_mux->nr_sessions; i++)
		if (ipc_mux->session[i].wwan)
			ipc_mux_session_reset(ipc_mux, i);

	ipc_imem_channel_close(ipc_mux->imem, ipc_mux->channel_id);

	/* Reset the MUX object. */
	ipc_mux->state = MUX_S_INACTIVE;
	ipc_mux->event = MUX_E_INACTIVE;
}

/* CP has interrupted AP. If AP is in IP MUX mode, execute the pending ops. */
static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg)
{
	enum mux_event order;
	bool success;
	int ret = -EIO;

	if (!ipc_mux->initialized) {
		ret = -EAGAIN;
		goto out;
	}

	order = msg->common.event;

	switch (ipc_mux->state) {
	case MUX_S_INACTIVE:
		if (order != MUX_E_MUX_SESSION_OPEN)
			goto out; /* Wait for the request to open a session */

		if (ipc_mux->event == MUX_E_INACTIVE)
			/* Establish the MUX channel and the new state. */
			ipc_mux->channel_id = ipc_mux_channel_create(ipc_mux);

		if (ipc_mux->state != MUX_S_ACTIVE) {
			ret = ipc_mux->channel_id; /* Missing the MUX channel */
			goto out;
		}

		/* Disable the TD update timer and open the first IP session. */
		ipc_imem_td_update_timer_suspend(ipc_mux->imem, true);
		ipc_mux->event = MUX_E_MUX_SESSION_OPEN;
		success = ipc_mux_session_open(ipc_mux, &msg->session_open);

		ipc_imem_td_update_timer_suspend(ipc_mux->imem, false);
		if (success)
			ret = ipc_mux->channel_id;
		goto out;

	case MUX_S_ACTIVE:
		switch (order) {
		case MUX_E_MUX_SESSION_OPEN:
			/* Disable the TD update timer and open a session */
			ipc_imem_td_update_timer_suspend(ipc_mux->imem, true);
			ipc_mux->event = MUX_E_MUX_SESSION_OPEN;
			success = ipc_mux_session_open(ipc_mux,
						       &msg->session_open);
			ipc_imem_td_update_timer_suspend(ipc_mux->imem, false);
			if (success)
				ret = ipc_mux->channel_id;
			goto out;

		case MUX_E_MUX_SESSION_CLOSE:
			/* Release an IP session. */
			ipc_mux->event = MUX_E_MUX_SESSION_CLOSE;
			ipc_mux_session_close(ipc_mux, &msg->session_close);
			ret = ipc_mux->channel_id;
			goto out;

		case MUX_E_MUX_CHANNEL_CLOSE:
			/* Close the MUX channel pipes. */
			ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE;
			ipc_mux_channel_close(ipc_mux, &msg->channel_close);
			ret = ipc_mux->channel_id;
			goto out;

		default:
			/* Invalid order. */
			goto out;
		}

	default:
		dev_err(ipc_mux->dev,
			"unexpected MUX transition: state=%d, event=%d",
			ipc_mux->state, ipc_mux->event);
	}
out:
	return ret;
}

struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg,
			      struct iosm_imem *imem)
{
	struct iosm_mux *ipc_mux = kzalloc(sizeof(*ipc_mux), GFP_KERNEL);
	int i, ul_tds, ul_td_size;
	struct sk_buff_head *free_list;
	struct sk_buff *skb;

	if (!ipc_mux)
		return NULL;

	ipc_mux->protocol = mux_cfg->protocol;
	ipc_mux->ul_flow = mux_cfg->ul_flow;
	ipc_mux->nr_sessions = mux_cfg->nr_sessions;
	ipc_mux->instance_id = mux_cfg->instance_id;
	ipc_mux->wwan_q_offset = 0;

	ipc_mux->pcie = imem->pcie;
	ipc_mux->imem = imem;
	ipc_mux->ipc_protocol = imem->ipc_protocol;
	ipc_mux->dev = imem->dev;
	ipc_mux->wwan = imem->wwan;

	/* Get the reference to the UL ADB list. */
	free_list = &ipc_mux->ul_adb.free_list;

	/* Initialize the list with free ADB. */
	skb_queue_head_init(free_list);

	ul_td_size = IPC_MEM_MAX_DL_MUX_LITE_BUF_SIZE;

	ul_tds = IPC_MEM_MAX_TDS_MUX_LITE_UL;

	ipc_mux->ul_adb.dest_skb = NULL;

	ipc_mux->initialized = true;
	ipc_mux->adb_prep_ongoing = false;
	ipc_mux->size_needed = 0;
	ipc_mux->ul_data_pend_bytes = 0;
	ipc_mux->state = MUX_S_INACTIVE;
	ipc_mux->ev_mux_net_transmit_pending = false;
	ipc_mux->tx_transaction_id = 0;
	ipc_mux->rr_next_session = 0;
	ipc_mux->event = MUX_E_INACTIVE;
	ipc_mux->channel_id = -1;
	ipc_mux->channel = NULL;

	/* Allocate the list of UL ADB. */
	for (i = 0; i < ul_tds; i++) {
		dma_addr_t mapping;

		skb = ipc_pcie_alloc_skb(ipc_mux->pcie, ul_td_size, GFP_ATOMIC,
					 &mapping, DMA_TO_DEVICE, 0);
		if (!skb) {
			ipc_mux_deinit(ipc_mux);
			return NULL;
		}
		/* Extend the UL ADB list. */
		skb_queue_tail(free_list, skb);
	}

	return ipc_mux;
}

/* Informs the network stack to restart transmission for all opened session if
 * Flow Control is not ON for that session.
 */
static void ipc_mux_restart_tx_for_all_sessions(struct iosm_mux *ipc_mux)
{
	struct mux_session *session;
	int idx;

	for (idx = 0; idx < ipc_mux->nr_sessions; idx++) {
		session = &ipc_mux->session[idx];

		if (!session->wwan)
			continue;

		/* If flow control of the session is OFF and if there was tx
		 * stop then restart. Inform the network interface to restart
		 * sending data.
		 */
		if (session->flow_ctl_mask == 0) {
			session->net_tx_stop = false;
			ipc_mux_netif_tx_flowctrl(session, idx, false);
		}
	}
}

/* Informs the network stack to stop sending further pkt for all opened
 * sessions
 */
static void ipc_mux_stop_netif_for_all_sessions(struct iosm_mux *ipc_mux)
{
	struct mux_session *session;
	int idx;

	for (idx = 0; idx < ipc_mux->nr_sessions; idx++) {
		session = &ipc_mux->session[idx];

		if (!session->wwan)
			continue;

		ipc_mux_netif_tx_flowctrl(session, session->if_id, true);
	}
}

void ipc_mux_check_n_restart_tx(struct iosm_mux *ipc_mux)
{
	if (ipc_mux->ul_flow == MUX_UL) {
		int low_thresh = IPC_MEM_MUX_UL_FLOWCTRL_LOW_B;

		if (ipc_mux->ul_data_pend_bytes < low_thresh)
			ipc_mux_restart_tx_for_all_sessions(ipc_mux);
	}
}

int ipc_mux_get_max_sessions(struct iosm_mux *ipc_mux)
{
	return ipc_mux ? ipc_mux->nr_sessions : -EFAULT;
}

enum ipc_mux_protocol ipc_mux_get_active_protocol(struct iosm_mux *ipc_mux)
{
	return ipc_mux ? ipc_mux->protocol : MUX_UNKNOWN;
}

int ipc_mux_open_session(struct iosm_mux *ipc_mux, int session_nr)
{
	struct mux_session_open *session_open;
	union mux_msg mux_msg;

	session_open = &mux_msg.session_open;
	session_open->event = MUX_E_MUX_SESSION_OPEN;

	session_open->if_id = cpu_to_le32(session_nr);
	ipc_mux->session[session_nr].flags |= IPC_MEM_WWAN_MUX;
	return ipc_mux_schedule(ipc_mux, &mux_msg);
}

int ipc_mux_close_session(struct iosm_mux *ipc_mux, int session_nr)
{
	struct mux_session_close *session_close;
	union mux_msg mux_msg;
	int ret_val;

	session_close = &mux_msg.session_close;
	session_close->event = MUX_E_MUX_SESSION_CLOSE;

	session_close->if_id = cpu_to_le32(session_nr);
	ret_val = ipc_mux_schedule(ipc_mux, &mux_msg);
	ipc_mux->session[session_nr].flags &= ~IPC_MEM_WWAN_MUX;

	return ret_val;
}

void ipc_mux_deinit(struct iosm_mux *ipc_mux)
{
	struct mux_channel_close *channel_close;
	struct sk_buff_head *free_list;
	union mux_msg mux_msg;
	struct sk_buff *skb;

	if (!ipc_mux->initialized)
		return;
	ipc_mux_stop_netif_for_all_sessions(ipc_mux);

	channel_close = &mux_msg.channel_close;
	channel_close->event = MUX_E_MUX_CHANNEL_CLOSE;
	ipc_mux_schedule(ipc_mux, &mux_msg);

	/* Empty the ADB free list. */
	free_list = &ipc_mux->ul_adb.free_list;

	/* Remove from the head of the downlink queue. */
	while ((skb = skb_dequeue(free_list)))
		ipc_pcie_kfree_skb(ipc_mux->pcie, skb);

	if (ipc_mux->channel) {
		ipc_mux->channel->ul_pipe.is_open = false;
		ipc_mux->channel->dl_pipe.is_open = false;
	}

	kfree(ipc_mux);
}
