// 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_MEM_MUX_IP_SESSION_ENTRIES) {
		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);
	ipc_mux->nr_sessions++;

	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_MEM_MUX_IP_SESSION_ENTRIES) {
		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);
	ipc_mux->nr_sessions--;
}

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_MEM_MUX_IP_SESSION_ENTRIES; 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);
			if (!ipc_mux->nr_sessions) {
				ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE;
				ipc_mux_channel_close(ipc_mux,
						      &msg->channel_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, j, ul_tds, ul_td_size;
	struct sk_buff_head *free_list;
	struct sk_buff *skb;
	int qlt_size;

	if (!ipc_mux)
		return NULL;

	ipc_mux->protocol = mux_cfg->protocol;
	ipc_mux->ul_flow = mux_cfg->ul_flow;
	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;

	if (ipc_mux->protocol != MUX_LITE) {
		qlt_size = offsetof(struct mux_qlth, ql) +
				MUX_QUEUE_LEVEL * sizeof(struct mux_qlth_ql);

		for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++) {
			ipc_mux->ul_adb.pp_qlt[i] = kzalloc(qlt_size,
							    GFP_ATOMIC);
			if (!ipc_mux->ul_adb.pp_qlt[i]) {
				for (j = i - 1; j >= 0; j--)
					kfree(ipc_mux->ul_adb.pp_qlt[j]);
				return NULL;
			}
		}

		ul_td_size = IPC_MEM_MAX_UL_ADB_BUF_SIZE;
		ul_tds = IPC_MEM_MAX_TDS_MUX_AGGR_UL;
	}

	/* 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_MEM_MUX_IP_SESSION_ENTRIES; 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_MEM_MUX_IP_SESSION_ENTRIES; 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_MEM_MUX_IP_SESSION_ENTRIES : -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);

	if (ipc_mux->state == MUX_S_ACTIVE) {
		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);
}
