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

#include <linux/nospec.h>

#include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_mux_codec.h"
#include "iosm_ipc_task_queue.h"

/* Test the link power state and send a MUX command in blocking mode. */
static int ipc_mux_tq_cmd_send(struct iosm_imem *ipc_imem, int arg, void *msg,
			       size_t size)
{
	struct iosm_mux *ipc_mux = ipc_imem->mux;
	const struct mux_acb *acb = msg;

	skb_queue_tail(&ipc_mux->channel->ul_list, acb->skb);
	ipc_imem_ul_send(ipc_mux->imem);

	return 0;
}

static int ipc_mux_acb_send(struct iosm_mux *ipc_mux, bool blocking)
{
	struct completion *completion = &ipc_mux->channel->ul_sem;
	int ret = ipc_task_queue_send_task(ipc_mux->imem, ipc_mux_tq_cmd_send,
					   0, &ipc_mux->acb,
					   sizeof(ipc_mux->acb), false);
	if (ret) {
		dev_err(ipc_mux->dev, "unable to send mux command");
		return ret;
	}

	/* if blocking, suspend the app and wait for irq in the flash or
	 * crash phase. return false on timeout to indicate failure.
	 */
	if (blocking) {
		u32 wait_time_milliseconds = IPC_MUX_CMD_RUN_DEFAULT_TIMEOUT;

		reinit_completion(completion);

		if (wait_for_completion_interruptible_timeout
		   (completion, msecs_to_jiffies(wait_time_milliseconds)) ==
		   0) {
			dev_err(ipc_mux->dev, "ch[%d] timeout",
				ipc_mux->channel_id);
			ipc_uevent_send(ipc_mux->imem->dev, UEVENT_MDM_TIMEOUT);
			return -ETIMEDOUT;
		}
	}

	return 0;
}

/* Initialize the command header. */
static void ipc_mux_acb_init(struct iosm_mux *ipc_mux)
{
	struct mux_acb *acb = &ipc_mux->acb;
	struct mux_acbh *header;

	header = (struct mux_acbh *)(acb->skb)->data;
	header->block_length = cpu_to_le32(sizeof(struct mux_acbh));
	header->first_cmd_index = header->block_length;
	header->signature = cpu_to_le32(IOSM_AGGR_MUX_SIG_ACBH);
	header->sequence_nr = cpu_to_le16(ipc_mux->acb_tx_sequence_nr++);
}

/* Add a command to the ACB. */
static struct mux_cmdh *ipc_mux_acb_add_cmd(struct iosm_mux *ipc_mux, u32 cmd,
					    void *param, u32 param_size)
{
	struct mux_acbh *header;
	struct mux_cmdh *cmdh;
	struct mux_acb *acb;

	acb = &ipc_mux->acb;
	header = (struct mux_acbh *)(acb->skb)->data;
	cmdh = (struct mux_cmdh *)
		((acb->skb)->data + le32_to_cpu(header->block_length));

	cmdh->signature = cpu_to_le32(MUX_SIG_CMDH);
	cmdh->command_type = cpu_to_le32(cmd);
	cmdh->if_id = acb->if_id;

	acb->cmd = cmd;
	cmdh->cmd_len = cpu_to_le16(offsetof(struct mux_cmdh, param) +
				    param_size);
	cmdh->transaction_id = cpu_to_le32(ipc_mux->tx_transaction_id++);
	if (param)
		memcpy(&cmdh->param, param, param_size);

	skb_put(acb->skb, le32_to_cpu(header->block_length) +
					le16_to_cpu(cmdh->cmd_len));

	return cmdh;
}

/* Prepare mux Command */
static struct mux_lite_cmdh *ipc_mux_lite_add_cmd(struct iosm_mux *ipc_mux,
						  u32 cmd, struct mux_acb *acb,
						  void *param, u32 param_size)
{
	struct mux_lite_cmdh *cmdh = (struct mux_lite_cmdh *)acb->skb->data;

	cmdh->signature = cpu_to_le32(MUX_SIG_CMDH);
	cmdh->command_type = cpu_to_le32(cmd);
	cmdh->if_id = acb->if_id;

	acb->cmd = cmd;

	cmdh->cmd_len = cpu_to_le16(offsetof(struct mux_lite_cmdh, param) +
				    param_size);
	cmdh->transaction_id = cpu_to_le32(ipc_mux->tx_transaction_id++);

	if (param)
		memcpy(&cmdh->param, param, param_size);

	skb_put(acb->skb, le16_to_cpu(cmdh->cmd_len));

	return cmdh;
}

static int ipc_mux_acb_alloc(struct iosm_mux *ipc_mux)
{
	struct mux_acb *acb = &ipc_mux->acb;
	struct sk_buff *skb;
	dma_addr_t mapping;

	/* Allocate skb memory for the uplink buffer. */
	skb = ipc_pcie_alloc_skb(ipc_mux->pcie, MUX_MAX_UL_ACB_BUF_SIZE,
				 GFP_ATOMIC, &mapping, DMA_TO_DEVICE, 0);
	if (!skb)
		return -ENOMEM;

	/* Save the skb address. */
	acb->skb = skb;

	memset(skb->data, 0, MUX_MAX_UL_ACB_BUF_SIZE);

	return 0;
}

int ipc_mux_dl_acb_send_cmds(struct iosm_mux *ipc_mux, u32 cmd_type, u8 if_id,
			     u32 transaction_id, union mux_cmd_param *param,
			     size_t res_size, bool blocking, bool respond)
{
	struct mux_acb *acb = &ipc_mux->acb;
	union mux_type_cmdh cmdh;
	int ret = 0;

	acb->if_id = if_id;
	ret = ipc_mux_acb_alloc(ipc_mux);
	if (ret)
		return ret;

	if (ipc_mux->protocol == MUX_LITE) {
		cmdh.ack_lite = ipc_mux_lite_add_cmd(ipc_mux, cmd_type, acb,
						     param, res_size);

		if (respond)
			cmdh.ack_lite->transaction_id =
					cpu_to_le32(transaction_id);
	} else {
		/* Initialize the ACB header. */
		ipc_mux_acb_init(ipc_mux);
		cmdh.ack_aggr = ipc_mux_acb_add_cmd(ipc_mux, cmd_type, param,
						    res_size);

		if (respond)
			cmdh.ack_aggr->transaction_id =
					cpu_to_le32(transaction_id);
	}
	ret = ipc_mux_acb_send(ipc_mux, blocking);

	return ret;
}

void ipc_mux_netif_tx_flowctrl(struct mux_session *session, int idx, bool on)
{
	/* Inform the network interface to start/stop flow ctrl */
	ipc_wwan_tx_flowctrl(session->wwan, idx, on);
}

static int ipc_mux_dl_cmdresps_decode_process(struct iosm_mux *ipc_mux,
					      union mux_cmd_param param,
					      __le32 command_type, u8 if_id,
					      __le32 transaction_id)
{
	struct mux_acb *acb = &ipc_mux->acb;

	switch (le32_to_cpu(command_type)) {
	case MUX_CMD_OPEN_SESSION_RESP:
	case MUX_CMD_CLOSE_SESSION_RESP:
		/* Resume the control application. */
		acb->got_param = param;
		break;

	case MUX_LITE_CMD_FLOW_CTL_ACK:
		/* This command type is not expected as response for
		 * Aggregation version of the protocol. So return non-zero.
		 */
		if (ipc_mux->protocol != MUX_LITE)
			return -EINVAL;

		dev_dbg(ipc_mux->dev, "if_id %u FLOW_CTL_ACK %u received",
			if_id, le32_to_cpu(transaction_id));
		break;

	case IOSM_AGGR_MUX_CMD_FLOW_CTL_ACK:
		/* This command type is not expected as response for
		 * Lite version of the protocol. So return non-zero.
		 */
		if (ipc_mux->protocol == MUX_LITE)
			return -EINVAL;
		break;

	default:
		return -EINVAL;
	}

	acb->wanted_response = MUX_CMD_INVALID;
	acb->got_response = le32_to_cpu(command_type);
	complete(&ipc_mux->channel->ul_sem);

	return 0;
}

static int ipc_mux_dl_cmds_decode_process(struct iosm_mux *ipc_mux,
					  union mux_cmd_param *param,
					  __le32 command_type, u8 if_id,
					  __le16 cmd_len, int size)
{
	struct mux_session *session;
	struct hrtimer *adb_timer;

	dev_dbg(ipc_mux->dev, "if_id[%d]: dlcmds decode process %d",
		if_id, le32_to_cpu(command_type));

	switch (le32_to_cpu(command_type)) {
	case MUX_LITE_CMD_FLOW_CTL:
	case IOSM_AGGR_MUX_CMD_FLOW_CTL_DISABLE:

		if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
			dev_err(ipc_mux->dev, "if_id [%d] not valid",
				if_id);
			return -EINVAL; /* No session interface id. */
		}

		session = &ipc_mux->session[if_id];
		adb_timer = &ipc_mux->imem->adb_timer;

		if (param->flow_ctl.mask == cpu_to_le32(0xFFFFFFFF)) {
			/* Backward Compatibility */
			if (cmd_len == cpu_to_le16(size))
				session->flow_ctl_mask =
					le32_to_cpu(param->flow_ctl.mask);
			else
				session->flow_ctl_mask = ~0;
			/* if CP asks for FLOW CTRL Enable
			 * then set our internal flow control Tx flag
			 * to limit uplink session queueing
			 */
			session->net_tx_stop = true;

			/* We have to call Finish ADB here.
			 * Otherwise any already queued data
			 * will be sent to CP when ADB is full
			 * for some other sessions.
			 */
			if (ipc_mux->protocol == MUX_AGGREGATION) {
				ipc_mux_ul_adb_finish(ipc_mux);
				ipc_imem_hrtimer_stop(adb_timer);
			}
			/* Update the stats */
			session->flow_ctl_en_cnt++;
		} else if (param->flow_ctl.mask == 0) {
			/* Just reset the Flow control mask and let
			 * mux_flow_ctrl_low_thre_b take control on
			 * our internal Tx flag and enabling kernel
			 * flow control
			 */
			dev_dbg(ipc_mux->dev, "if_id[%u] flow_ctl mask 0x%08X",
				if_id, le32_to_cpu(param->flow_ctl.mask));
			/* Backward Compatibility */
			if (cmd_len == cpu_to_le16(size))
				session->flow_ctl_mask =
					le32_to_cpu(param->flow_ctl.mask);
			else
				session->flow_ctl_mask = 0;
			/* Update the stats */
			session->flow_ctl_dis_cnt++;
		} else {
			break;
		}

		ipc_mux->acc_adb_size = 0;
		ipc_mux->acc_payload_size = 0;

		dev_dbg(ipc_mux->dev, "if_id[%u] FLOW CTRL 0x%08X", if_id,
			le32_to_cpu(param->flow_ctl.mask));
		break;

	case MUX_LITE_CMD_LINK_STATUS_REPORT:
		break;

	default:
		return -EINVAL;
	}
	return 0;
}

/* Decode and Send appropriate response to a command block. */
static void ipc_mux_dl_cmd_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
{
	struct mux_lite_cmdh *cmdh = (struct mux_lite_cmdh *)skb->data;
	__le32 trans_id = cmdh->transaction_id;
	int size;

	if (ipc_mux_dl_cmdresps_decode_process(ipc_mux, cmdh->param,
					       cmdh->command_type, cmdh->if_id,
					       cmdh->transaction_id)) {
		/* Unable to decode command response indicates the cmd_type
		 * may be a command instead of response. So try to decoding it.
		 */
		size = offsetof(struct mux_lite_cmdh, param) +
				sizeof(cmdh->param.flow_ctl);
		if (!ipc_mux_dl_cmds_decode_process(ipc_mux, &cmdh->param,
						    cmdh->command_type,
						    cmdh->if_id,
						    cmdh->cmd_len, size)) {
			/* Decoded command may need a response. Give the
			 * response according to the command type.
			 */
			union mux_cmd_param *mux_cmd = NULL;
			size_t size = 0;
			u32 cmd = MUX_LITE_CMD_LINK_STATUS_REPORT_RESP;

			if (cmdh->command_type ==
			    cpu_to_le32(MUX_LITE_CMD_LINK_STATUS_REPORT)) {
				mux_cmd = &cmdh->param;
				mux_cmd->link_status_resp.response =
					cpu_to_le32(MUX_CMD_RESP_SUCCESS);
				/* response field is u32 */
				size = sizeof(u32);
			} else if (cmdh->command_type ==
				   cpu_to_le32(MUX_LITE_CMD_FLOW_CTL)) {
				cmd = MUX_LITE_CMD_FLOW_CTL_ACK;
			} else {
				return;
			}

			if (ipc_mux_dl_acb_send_cmds(ipc_mux, cmd, cmdh->if_id,
						     le32_to_cpu(trans_id),
						     mux_cmd, size, false,
						     true))
				dev_err(ipc_mux->dev,
					"if_id %d: cmd send failed",
					cmdh->if_id);
		}
	}
}

/* Pass the DL packet to the netif layer. */
static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
			       struct iosm_wwan *wwan, u32 offset,
			       u8 service_class, struct sk_buff *skb,
			       u32 pkt_len)
{
	struct sk_buff *dest_skb = skb_clone(skb, GFP_ATOMIC);

	if (!dest_skb)
		return -ENOMEM;

	skb_pull(dest_skb, offset);
	skb_trim(dest_skb, pkt_len);
	/* Pass the packet to the netif layer. */
	dest_skb->priority = service_class;

	return ipc_wwan_receive(wwan, dest_skb, false, if_id);
}

/* Decode Flow Credit Table in the block */
static void ipc_mux_dl_fcth_decode(struct iosm_mux *ipc_mux,
				   unsigned char *block)
{
	struct ipc_mem_lite_gen_tbl *fct = (struct ipc_mem_lite_gen_tbl *)block;
	struct iosm_wwan *wwan;
	int ul_credits;
	int if_id;

	if (fct->vfl_length != sizeof(fct->vfl.nr_of_bytes)) {
		dev_err(ipc_mux->dev, "unexpected FCT length: %d",
			fct->vfl_length);
		return;
	}

	if_id = fct->if_id;
	if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
		dev_err(ipc_mux->dev, "not supported if_id: %d", if_id);
		return;
	}

	/* Is the session active ? */
	if_id = array_index_nospec(if_id, IPC_MEM_MUX_IP_SESSION_ENTRIES);
	wwan = ipc_mux->session[if_id].wwan;
	if (!wwan) {
		dev_err(ipc_mux->dev, "session Net ID is NULL");
		return;
	}

	ul_credits = le32_to_cpu(fct->vfl.nr_of_bytes);

	dev_dbg(ipc_mux->dev, "Flow_Credit:: if_id[%d] Old: %d Grants: %d",
		if_id, ipc_mux->session[if_id].ul_flow_credits, ul_credits);

	/* Update the Flow Credit information from ADB */
	ipc_mux->session[if_id].ul_flow_credits += ul_credits;

	/* Check whether the TX can be started */
	if (ipc_mux->session[if_id].ul_flow_credits > 0) {
		ipc_mux->session[if_id].net_tx_stop = false;
		ipc_mux_netif_tx_flowctrl(&ipc_mux->session[if_id],
					  ipc_mux->session[if_id].if_id, false);
	}
}

/* Decode non-aggregated datagram */
static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
				   struct sk_buff *skb)
{
	u32 pad_len, packet_offset, adgh_len;
	struct iosm_wwan *wwan;
	struct mux_adgh *adgh;
	u8 *block = skb->data;
	int rc = 0;
	u8 if_id;

	adgh = (struct mux_adgh *)block;

	if (adgh->signature != cpu_to_le32(IOSM_AGGR_MUX_SIG_ADGH)) {
		dev_err(ipc_mux->dev, "invalid ADGH signature received");
		return;
	}

	if_id = adgh->if_id;
	if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
		dev_err(ipc_mux->dev, "invalid if_id while decoding %d", if_id);
		return;
	}

	/* Is the session active ? */
	if_id = array_index_nospec(if_id, IPC_MEM_MUX_IP_SESSION_ENTRIES);
	wwan = ipc_mux->session[if_id].wwan;
	if (!wwan) {
		dev_err(ipc_mux->dev, "session Net ID is NULL");
		return;
	}

	/* Store the pad len for the corresponding session
	 * Pad bytes as negotiated in the open session less the header size
	 * (see session management chapter for details).
	 * If resulting padding is zero or less, the additional head padding is
	 * omitted. For e.g., if HEAD_PAD_LEN = 16 or less, this field is
	 * omitted if HEAD_PAD_LEN = 20, then this field will have 4 bytes
	 * set to zero
	 */
	pad_len =
		ipc_mux->session[if_id].dl_head_pad_len - IPC_MEM_DL_ETH_OFFSET;
	packet_offset = sizeof(*adgh) + pad_len;

	if_id += ipc_mux->wwan_q_offset;
	adgh_len = le16_to_cpu(adgh->length);

	/* Pass the packet to the netif layer */
	rc = ipc_mux_net_receive(ipc_mux, if_id, wwan, packet_offset,
				 adgh->service_class, skb,
				 adgh_len - packet_offset);
	if (rc) {
		dev_err(ipc_mux->dev, "mux adgh decoding error");
		return;
	}
	ipc_mux->session[if_id].flush = 1;
}

static void ipc_mux_dl_acbcmd_decode(struct iosm_mux *ipc_mux,
				     struct mux_cmdh *cmdh, int size)
{
	u32 link_st  = IOSM_AGGR_MUX_CMD_LINK_STATUS_REPORT_RESP;
	u32 fctl_dis = IOSM_AGGR_MUX_CMD_FLOW_CTL_DISABLE;
	u32 fctl_ena = IOSM_AGGR_MUX_CMD_FLOW_CTL_ENABLE;
	u32 fctl_ack = IOSM_AGGR_MUX_CMD_FLOW_CTL_ACK;
	union mux_cmd_param *cmd_p = NULL;
	u32 cmd = link_st;
	u32 trans_id;

	if (!ipc_mux_dl_cmds_decode_process(ipc_mux, &cmdh->param,
					    cmdh->command_type, cmdh->if_id,
					    cmdh->cmd_len, size)) {
		size = 0;
		if (cmdh->command_type == cpu_to_le32(link_st)) {
			cmd_p = &cmdh->param;
			cmd_p->link_status_resp.response = MUX_CMD_RESP_SUCCESS;
		} else if ((cmdh->command_type == cpu_to_le32(fctl_ena)) ||
				(cmdh->command_type == cpu_to_le32(fctl_dis))) {
			cmd = fctl_ack;
		} else {
			return;
			}
		trans_id = le32_to_cpu(cmdh->transaction_id);
		ipc_mux_dl_acb_send_cmds(ipc_mux, cmd, cmdh->if_id,
					 trans_id, cmd_p, size, false, true);
	}
}

/* Decode an aggregated command block. */
static void ipc_mux_dl_acb_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
{
	struct mux_acbh *acbh;
	struct mux_cmdh *cmdh;
	u32 next_cmd_index;
	u8 *block;
	int size;

	acbh = (struct mux_acbh *)(skb->data);
	block = (u8 *)(skb->data);

	next_cmd_index = le32_to_cpu(acbh->first_cmd_index);
	next_cmd_index = array_index_nospec(next_cmd_index,
					    sizeof(struct mux_cmdh));

	while (next_cmd_index != 0) {
		cmdh = (struct mux_cmdh *)&block[next_cmd_index];
		next_cmd_index = le32_to_cpu(cmdh->next_cmd_index);
		if (ipc_mux_dl_cmdresps_decode_process(ipc_mux, cmdh->param,
						       cmdh->command_type,
						       cmdh->if_id,
						       cmdh->transaction_id)) {
			size = offsetof(struct mux_cmdh, param) +
				sizeof(cmdh->param.flow_ctl);
			ipc_mux_dl_acbcmd_decode(ipc_mux, cmdh, size);
		}
	}
}

/* process datagram */
static int mux_dl_process_dg(struct iosm_mux *ipc_mux, struct mux_adbh *adbh,
			     struct mux_adth_dg *dg, struct sk_buff *skb,
			     int if_id, int nr_of_dg)
{
	u32 dl_head_pad_len = ipc_mux->session[if_id].dl_head_pad_len;
	u32 packet_offset, i, rc, dg_len;

	for (i = 0; i < nr_of_dg; i++, dg++) {
		if (le32_to_cpu(dg->datagram_index)
				< sizeof(struct mux_adbh))
			goto dg_error;

		/* Is the packet inside of the ADB */
		if (le32_to_cpu(dg->datagram_index) >=
					le32_to_cpu(adbh->block_length)) {
			goto dg_error;
		} else {
			packet_offset =
				le32_to_cpu(dg->datagram_index) +
				dl_head_pad_len;
			dg_len = le16_to_cpu(dg->datagram_length);
			/* Pass the packet to the netif layer. */
			rc = ipc_mux_net_receive(ipc_mux, if_id, ipc_mux->wwan,
						 packet_offset,
						 dg->service_class, skb,
						 dg_len - dl_head_pad_len);
			if (rc)
				goto dg_error;
		}
	}
	return 0;
dg_error:
	return -1;
}

/* Decode an aggregated data block. */
static void mux_dl_adb_decode(struct iosm_mux *ipc_mux,
			      struct sk_buff *skb)
{
	struct mux_adth_dg *dg;
	struct iosm_wwan *wwan;
	struct mux_adbh *adbh;
	struct mux_adth *adth;
	int nr_of_dg, if_id;
	u32 adth_index;
	u8 *block;

	block = skb->data;
	adbh = (struct mux_adbh *)block;

	/* Process the aggregated datagram tables. */
	adth_index = le32_to_cpu(adbh->first_table_index);

	/* Has CP sent an empty ADB ? */
	if (adth_index < 1) {
		dev_err(ipc_mux->dev, "unexpected empty ADB");
		goto adb_decode_err;
	}

	/* Loop through mixed session tables. */
	while (adth_index) {
		/* Get the reference to the table header. */
		adth = (struct mux_adth *)(block + adth_index);

		/* Get the interface id and map it to the netif id. */
		if_id = adth->if_id;
		if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES)
			goto adb_decode_err;

		if_id = array_index_nospec(if_id,
					   IPC_MEM_MUX_IP_SESSION_ENTRIES);

		/* Is the session active ? */
		wwan = ipc_mux->session[if_id].wwan;
		if (!wwan)
			goto adb_decode_err;

		/* Consistency checks for aggregated datagram table. */
		if (adth->signature != cpu_to_le32(IOSM_AGGR_MUX_SIG_ADTH))
			goto adb_decode_err;

		if (le16_to_cpu(adth->table_length) < (sizeof(struct mux_adth) -
				sizeof(struct mux_adth_dg)))
			goto adb_decode_err;

		/* Calculate the number of datagrams. */
		nr_of_dg = (le16_to_cpu(adth->table_length) -
					sizeof(struct mux_adth) +
					sizeof(struct mux_adth_dg)) /
					sizeof(struct mux_adth_dg);

		/* Is the datagram table empty ? */
		if (nr_of_dg < 1) {
			dev_err(ipc_mux->dev,
				"adthidx=%u,nr_of_dg=%d,next_tblidx=%u",
				adth_index, nr_of_dg,
				le32_to_cpu(adth->next_table_index));

			/* Move to the next aggregated datagram table. */
			adth_index = le32_to_cpu(adth->next_table_index);
			continue;
		}

		/* New aggregated datagram table. */
		dg = &adth->dg;
		if (mux_dl_process_dg(ipc_mux, adbh, dg, skb, if_id,
				      nr_of_dg) < 0)
			goto adb_decode_err;

		/* mark session for final flush */
		ipc_mux->session[if_id].flush = 1;

		/* Move to the next aggregated datagram table. */
		adth_index = le32_to_cpu(adth->next_table_index);
	}

adb_decode_err:
	return;
}

/**
 * ipc_mux_dl_decode -  Route the DL packet through the IP MUX layer
 *                      depending on Header.
 * @ipc_mux:            Pointer to MUX data-struct
 * @skb:                Pointer to ipc_skb.
 */
void ipc_mux_dl_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
{
	u32 signature;

	if (!skb->data)
		return;

	/* Decode the MUX header type. */
	signature = le32_to_cpup((__le32 *)skb->data);

	switch (signature) {
	case IOSM_AGGR_MUX_SIG_ADBH:	/* Aggregated Data Block Header */
		mux_dl_adb_decode(ipc_mux, skb);
		break;
	case IOSM_AGGR_MUX_SIG_ADGH:
		ipc_mux_dl_adgh_decode(ipc_mux, skb);
		break;
	case MUX_SIG_FCTH:
		ipc_mux_dl_fcth_decode(ipc_mux, skb->data);
		break;
	case IOSM_AGGR_MUX_SIG_ACBH:	/* Aggregated Command Block Header */
		ipc_mux_dl_acb_decode(ipc_mux, skb);
		break;
	case MUX_SIG_CMDH:
		ipc_mux_dl_cmd_decode(ipc_mux, skb);
		break;

	default:
		dev_err(ipc_mux->dev, "invalid ABH signature");
	}

	ipc_pcie_kfree_skb(ipc_mux->pcie, skb);
}

static int ipc_mux_ul_skb_alloc(struct iosm_mux *ipc_mux,
				struct mux_adb *ul_adb, u32 type)
{
	/* Take the first element of the free list. */
	struct sk_buff *skb = skb_dequeue(&ul_adb->free_list);
	u32 no_if = IPC_MEM_MUX_IP_SESSION_ENTRIES;
	u32 *next_tb_id;
	int qlt_size;
	u32 if_id;

	if (!skb)
		return -EBUSY; /* Wait for a free ADB skb. */

	/* Mark it as UL ADB to select the right free operation. */
	IPC_CB(skb)->op_type = (u8)UL_MUX_OP_ADB;

	switch (type) {
	case IOSM_AGGR_MUX_SIG_ADBH:
		/* Save the ADB memory settings. */
		ul_adb->dest_skb = skb;
		ul_adb->buf = skb->data;
		ul_adb->size = IPC_MEM_MAX_ADB_BUF_SIZE;

		/* reset statistic counter */
		ul_adb->if_cnt = 0;
		ul_adb->payload_size = 0;
		ul_adb->dg_cnt_total = 0;

		/* Initialize the ADBH. */
		ul_adb->adbh = (struct mux_adbh *)ul_adb->buf;
		memset(ul_adb->adbh, 0, sizeof(struct mux_adbh));
		ul_adb->adbh->signature = cpu_to_le32(IOSM_AGGR_MUX_SIG_ADBH);
		ul_adb->adbh->block_length =
					cpu_to_le32(sizeof(struct mux_adbh));
		next_tb_id = (unsigned int *)&ul_adb->adbh->first_table_index;
		ul_adb->next_table_index = next_tb_id;

		/* Clear the local copy of DGs for new ADB */
		memset(ul_adb->dg, 0, sizeof(ul_adb->dg));

		/* Clear the DG count and QLT updated status for new ADB */
		for (if_id = 0; if_id < no_if; if_id++) {
			ul_adb->dg_count[if_id] = 0;
			ul_adb->qlt_updated[if_id] = 0;
		}
		break;

	case IOSM_AGGR_MUX_SIG_ADGH:
		/* Save the ADB memory settings. */
		ul_adb->dest_skb = skb;
		ul_adb->buf = skb->data;
		ul_adb->size = IPC_MEM_MAX_DL_MUX_LITE_BUF_SIZE;
		/* reset statistic counter */
		ul_adb->if_cnt = 0;
		ul_adb->payload_size = 0;
		ul_adb->dg_cnt_total = 0;

		ul_adb->adgh = (struct mux_adgh *)skb->data;
		memset(ul_adb->adgh, 0, sizeof(struct mux_adgh));
		break;

	case MUX_SIG_QLTH:
		qlt_size = offsetof(struct ipc_mem_lite_gen_tbl, vfl) +
			   (MUX_QUEUE_LEVEL * sizeof(struct mux_lite_vfl));

		if (qlt_size > IPC_MEM_MAX_DL_MUX_LITE_BUF_SIZE) {
			dev_err(ipc_mux->dev,
				"can't support. QLT size:%d SKB size: %d",
				qlt_size, IPC_MEM_MAX_DL_MUX_LITE_BUF_SIZE);
			return -ERANGE;
		}

		ul_adb->qlth_skb = skb;
		memset((ul_adb->qlth_skb)->data, 0, qlt_size);
		skb_put(skb, qlt_size);
		break;
	}

	return 0;
}

static void ipc_mux_ul_adgh_finish(struct iosm_mux *ipc_mux)
{
	struct mux_adb *ul_adb = &ipc_mux->ul_adb;
	u16 adgh_len;
	long long bytes;
	char *str;

	if (!ul_adb->dest_skb) {
		dev_err(ipc_mux->dev, "no dest skb");
		return;
	}

	adgh_len = le16_to_cpu(ul_adb->adgh->length);
	skb_put(ul_adb->dest_skb, adgh_len);
	skb_queue_tail(&ipc_mux->channel->ul_list, ul_adb->dest_skb);
	ul_adb->dest_skb = NULL;

	if (ipc_mux->ul_flow == MUX_UL_ON_CREDITS) {
		struct mux_session *session;

		session = &ipc_mux->session[ul_adb->adgh->if_id];
		str = "available_credits";
		bytes = (long long)session->ul_flow_credits;

	} else {
		str = "pend_bytes";
		bytes = ipc_mux->ul_data_pend_bytes;
		ipc_mux->ul_data_pend_bytes = ipc_mux->ul_data_pend_bytes +
					      adgh_len;
	}

	dev_dbg(ipc_mux->dev, "UL ADGH: size=%u, if_id=%d, payload=%d, %s=%lld",
		adgh_len, ul_adb->adgh->if_id, ul_adb->payload_size,
		str, bytes);
}

static void ipc_mux_ul_encode_adth(struct iosm_mux *ipc_mux,
				   struct mux_adb *ul_adb, int *out_offset)
{
	int i, qlt_size, offset = *out_offset;
	struct mux_qlth *p_adb_qlt;
	struct mux_adth_dg *dg;
	struct mux_adth *adth;
	u16 adth_dg_size;
	u32 *next_tb_id;

	qlt_size = offsetof(struct mux_qlth, ql) +
			MUX_QUEUE_LEVEL * sizeof(struct mux_qlth_ql);

	for (i = 0; i < ipc_mux->nr_sessions; i++) {
		if (ul_adb->dg_count[i] > 0) {
			adth_dg_size = offsetof(struct mux_adth, dg) +
					ul_adb->dg_count[i] * sizeof(*dg);

			*ul_adb->next_table_index = offset;
			adth = (struct mux_adth *)&ul_adb->buf[offset];
			next_tb_id = (unsigned int *)&adth->next_table_index;
			ul_adb->next_table_index = next_tb_id;
			offset += adth_dg_size;
			adth->signature = cpu_to_le32(IOSM_AGGR_MUX_SIG_ADTH);
			adth->if_id = i;
			adth->table_length = cpu_to_le16(adth_dg_size);
			adth_dg_size -= offsetof(struct mux_adth, dg);
			memcpy(&adth->dg, ul_adb->dg[i], adth_dg_size);
			ul_adb->if_cnt++;
		}

		if (ul_adb->qlt_updated[i]) {
			*ul_adb->next_table_index = offset;
			p_adb_qlt = (struct mux_qlth *)&ul_adb->buf[offset];
			ul_adb->next_table_index =
				(u32 *)&p_adb_qlt->next_table_index;
			memcpy(p_adb_qlt, ul_adb->pp_qlt[i], qlt_size);
			offset += qlt_size;
		}
	}
	*out_offset = offset;
}

/**
 * ipc_mux_ul_adb_finish - Add the TD of the aggregated session packets to TDR.
 * @ipc_mux:               Pointer to MUX data-struct.
 */
void ipc_mux_ul_adb_finish(struct iosm_mux *ipc_mux)
{
	bool ul_data_pend = false;
	struct mux_adb *ul_adb;
	unsigned long flags;
	int offset;

	ul_adb = &ipc_mux->ul_adb;
	if (!ul_adb->dest_skb)
		return;

	offset = *ul_adb->next_table_index;
	ipc_mux_ul_encode_adth(ipc_mux, ul_adb, &offset);
	ul_adb->adbh->block_length = cpu_to_le32(offset);

	if (le32_to_cpu(ul_adb->adbh->block_length) > ul_adb->size) {
		ul_adb->dest_skb = NULL;
		return;
	}

	*ul_adb->next_table_index = 0;
	ul_adb->adbh->sequence_nr = cpu_to_le16(ipc_mux->adb_tx_sequence_nr++);
	skb_put(ul_adb->dest_skb, le32_to_cpu(ul_adb->adbh->block_length));

	spin_lock_irqsave(&(&ipc_mux->channel->ul_list)->lock, flags);
	__skb_queue_tail(&ipc_mux->channel->ul_list,  ul_adb->dest_skb);
	spin_unlock_irqrestore(&(&ipc_mux->channel->ul_list)->lock, flags);

	ul_adb->dest_skb = NULL;
	/* Updates the TDs with ul_list */
	ul_data_pend = ipc_imem_ul_write_td(ipc_mux->imem);

	/* Delay the doorbell irq */
	if (ul_data_pend)
		ipc_imem_td_update_timer_start(ipc_mux->imem);

	ipc_mux->acc_adb_size +=  le32_to_cpu(ul_adb->adbh->block_length);
	ipc_mux->acc_payload_size += ul_adb->payload_size;
	ipc_mux->ul_data_pend_bytes += ul_adb->payload_size;
}

/* Allocates an ADB from the free list and initializes it with ADBH  */
static bool ipc_mux_ul_adb_allocate(struct iosm_mux *ipc_mux,
				    struct mux_adb *adb, int *size_needed,
				    u32 type)
{
	bool ret_val = false;
	int status;

	if (!adb->dest_skb) {
		/* Allocate memory for the ADB including of the
		 * datagram table header.
		 */
		status = ipc_mux_ul_skb_alloc(ipc_mux, adb, type);
		if (status)
			/* Is a pending ADB available ? */
			ret_val = true; /* None. */

		/* Update size need to zero only for new ADB memory */
		*size_needed = 0;
	}

	return ret_val;
}

/* Informs the network stack to stop sending further packets for all opened
 * sessions
 */
static void ipc_mux_stop_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;

		session->net_tx_stop = true;
	}
}

/* Sends Queue Level Table of all opened sessions */
static bool ipc_mux_lite_send_qlt(struct iosm_mux *ipc_mux)
{
	struct ipc_mem_lite_gen_tbl *qlt;
	struct mux_session *session;
	bool qlt_updated = false;
	int i;
	int qlt_size;

	if (!ipc_mux->initialized || ipc_mux->state != MUX_S_ACTIVE)
		return qlt_updated;

	qlt_size = offsetof(struct ipc_mem_lite_gen_tbl, vfl) +
		   MUX_QUEUE_LEVEL * sizeof(struct mux_lite_vfl);

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

		if (!session->wwan || session->flow_ctl_mask)
			continue;

		if (ipc_mux_ul_skb_alloc(ipc_mux, &ipc_mux->ul_adb,
					 MUX_SIG_QLTH)) {
			dev_err(ipc_mux->dev,
				"no reserved mem to send QLT of if_id: %d", i);
			break;
		}

		/* Prepare QLT */
		qlt = (struct ipc_mem_lite_gen_tbl *)(ipc_mux->ul_adb.qlth_skb)
			      ->data;
		qlt->signature = cpu_to_le32(MUX_SIG_QLTH);
		qlt->length = cpu_to_le16(qlt_size);
		qlt->if_id = i;
		qlt->vfl_length = MUX_QUEUE_LEVEL * sizeof(struct mux_lite_vfl);
		qlt->reserved[0] = 0;
		qlt->reserved[1] = 0;

		qlt->vfl.nr_of_bytes = cpu_to_le32(session->ul_list.qlen);

		/* Add QLT to the transfer list. */
		skb_queue_tail(&ipc_mux->channel->ul_list,
			       ipc_mux->ul_adb.qlth_skb);

		qlt_updated = true;
		ipc_mux->ul_adb.qlth_skb = NULL;
	}

	if (qlt_updated)
		/* Updates the TDs with ul_list */
		(void)ipc_imem_ul_write_td(ipc_mux->imem);

	return qlt_updated;
}

/* Checks the available credits for the specified session and returns
 * number of packets for which credits are available.
 */
static int ipc_mux_ul_bytes_credits_check(struct iosm_mux *ipc_mux,
					  struct mux_session *session,
					  struct sk_buff_head *ul_list,
					  int max_nr_of_pkts)
{
	int pkts_to_send = 0;
	struct sk_buff *skb;
	int credits = 0;

	if (ipc_mux->ul_flow == MUX_UL_ON_CREDITS) {
		credits = session->ul_flow_credits;
		if (credits <= 0) {
			dev_dbg(ipc_mux->dev,
				"FC::if_id[%d] Insuff.Credits/Qlen:%d/%u",
				session->if_id, session->ul_flow_credits,
				session->ul_list.qlen); /* nr_of_bytes */
			return 0;
		}
	} else {
		credits = IPC_MEM_MUX_UL_FLOWCTRL_HIGH_B -
			  ipc_mux->ul_data_pend_bytes;
		if (credits <= 0) {
			ipc_mux_stop_tx_for_all_sessions(ipc_mux);

			dev_dbg(ipc_mux->dev,
				"if_id[%d] encod. fail Bytes: %llu, thresh: %d",
				session->if_id, ipc_mux->ul_data_pend_bytes,
				IPC_MEM_MUX_UL_FLOWCTRL_HIGH_B);
			return 0;
		}
	}

	/* Check if there are enough credits/bytes available to send the
	 * requested max_nr_of_pkts. Otherwise restrict the nr_of_pkts
	 * depending on available credits.
	 */
	skb_queue_walk(ul_list, skb)
	{
		if (!(credits >= skb->len && pkts_to_send < max_nr_of_pkts))
			break;
		credits -= skb->len;
		pkts_to_send++;
	}

	return pkts_to_send;
}

/* Encode the UL IP packet according to Lite spec. */
static int ipc_mux_ul_adgh_encode(struct iosm_mux *ipc_mux, int session_id,
				  struct mux_session *session,
				  struct sk_buff_head *ul_list,
				  struct mux_adb *adb, int nr_of_pkts)
{
	int offset = sizeof(struct mux_adgh);
	int adb_updated = -EINVAL;
	struct sk_buff *src_skb;
	int aligned_size = 0;
	int nr_of_skb = 0;
	u32 pad_len = 0;

	/* Re-calculate the number of packets depending on number of bytes to be
	 * processed/available credits.
	 */
	nr_of_pkts = ipc_mux_ul_bytes_credits_check(ipc_mux, session, ul_list,
						    nr_of_pkts);

	/* If calculated nr_of_pkts from available credits is <= 0
	 * then nothing to do.
	 */
	if (nr_of_pkts <= 0)
		return 0;

	/* Read configured UL head_pad_length for session.*/
	if (session->ul_head_pad_len > IPC_MEM_DL_ETH_OFFSET)
		pad_len = session->ul_head_pad_len - IPC_MEM_DL_ETH_OFFSET;

	/* Process all pending UL packets for this session
	 * depending on the allocated datagram table size.
	 */
	while (nr_of_pkts > 0) {
		/* get destination skb allocated */
		if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed,
					    IOSM_AGGR_MUX_SIG_ADGH)) {
			dev_err(ipc_mux->dev, "no reserved memory for ADGH");
			return -ENOMEM;
		}

		/* Peek at the head of the list. */
		src_skb = skb_peek(ul_list);
		if (!src_skb) {
			dev_err(ipc_mux->dev,
				"skb peek return NULL with count : %d",
				nr_of_pkts);
			break;
		}

		/* Calculate the memory value. */
		aligned_size = ALIGN((pad_len + src_skb->len), 4);

		ipc_mux->size_needed = sizeof(struct mux_adgh) + aligned_size;

		if (ipc_mux->size_needed > adb->size) {
			dev_dbg(ipc_mux->dev, "size needed %d, adgh size %d",
				ipc_mux->size_needed, adb->size);
			/* Return 1 if any IP packet is added to the transfer
			 * list.
			 */
			return nr_of_skb ? 1 : 0;
		}

		/* Add buffer (without head padding to next pending transfer) */
		memcpy(adb->buf + offset + pad_len, src_skb->data,
		       src_skb->len);

		adb->adgh->signature = cpu_to_le32(IOSM_AGGR_MUX_SIG_ADGH);
		adb->adgh->if_id = session_id;
		adb->adgh->length =
			cpu_to_le16(sizeof(struct mux_adgh) + pad_len +
				    src_skb->len);
		adb->adgh->service_class = src_skb->priority;
		adb->adgh->next_count = --nr_of_pkts;
		adb->dg_cnt_total++;
		adb->payload_size += src_skb->len;

		if (ipc_mux->ul_flow == MUX_UL_ON_CREDITS)
			/* Decrement the credit value as we are processing the
			 * datagram from the UL list.
			 */
			session->ul_flow_credits -= src_skb->len;

		/* Remove the processed elements and free it. */
		src_skb = skb_dequeue(ul_list);
		dev_kfree_skb(src_skb);
		nr_of_skb++;

		ipc_mux_ul_adgh_finish(ipc_mux);
	}

	if (nr_of_skb) {
		/* Send QLT info to modem if pending bytes > high watermark
		 * in case of mux lite
		 */
		if (ipc_mux->ul_flow == MUX_UL_ON_CREDITS ||
		    ipc_mux->ul_data_pend_bytes >=
			    IPC_MEM_MUX_UL_FLOWCTRL_LOW_B)
			adb_updated = ipc_mux_lite_send_qlt(ipc_mux);
		else
			adb_updated = 1;

		/* Updates the TDs with ul_list */
		(void)ipc_imem_ul_write_td(ipc_mux->imem);
	}

	return adb_updated;
}

/**
 * ipc_mux_ul_adb_update_ql - Adds Queue Level Table and Queue Level to ADB
 * @ipc_mux:            pointer to MUX instance data
 * @p_adb:              pointer to UL aggegated data block
 * @session_id:         session id
 * @qlth_n_ql_size:     Length (in bytes) of the datagram table
 * @ul_list:            pointer to skb buffer head
 */
void ipc_mux_ul_adb_update_ql(struct iosm_mux *ipc_mux, struct mux_adb *p_adb,
			      int session_id, int qlth_n_ql_size,
			      struct sk_buff_head *ul_list)
{
	int qlevel = ul_list->qlen;
	struct mux_qlth *p_qlt;

	p_qlt = (struct mux_qlth *)p_adb->pp_qlt[session_id];

	/* Initialize QLTH if not been done */
	if (p_adb->qlt_updated[session_id] == 0) {
		p_qlt->signature = cpu_to_le32(MUX_SIG_QLTH);
		p_qlt->if_id = session_id;
		p_qlt->table_length = cpu_to_le16(qlth_n_ql_size);
		p_qlt->reserved = 0;
		p_qlt->reserved2 = 0;
	}

	/* Update Queue Level information always */
	p_qlt->ql.nr_of_bytes = cpu_to_le32(qlevel);
	p_adb->qlt_updated[session_id] = 1;
}

/* Update the next table index. */
static int mux_ul_dg_update_tbl_index(struct iosm_mux *ipc_mux,
				      int session_id,
				      struct sk_buff_head *ul_list,
				      struct mux_adth_dg *dg,
				      int aligned_size,
				      u32 qlth_n_ql_size,
				      struct mux_adb *adb,
				      struct sk_buff *src_skb)
{
	ipc_mux_ul_adb_update_ql(ipc_mux, adb, session_id,
				 qlth_n_ql_size, ul_list);
	ipc_mux_ul_adb_finish(ipc_mux);
	if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed,
				    IOSM_AGGR_MUX_SIG_ADBH))
		return -ENOMEM;

	ipc_mux->size_needed = le32_to_cpu(adb->adbh->block_length);

	ipc_mux->size_needed += offsetof(struct mux_adth, dg);
	ipc_mux->size_needed += qlth_n_ql_size;
	ipc_mux->size_needed += sizeof(*dg) + aligned_size;
	return 0;
}

/* Process encode session UL data. */
static int mux_ul_dg_encode(struct iosm_mux *ipc_mux, struct mux_adb *adb,
			    struct mux_adth_dg *dg,
			    struct sk_buff_head *ul_list,
			    struct sk_buff *src_skb, int session_id,
			    int pkt_to_send, u32 qlth_n_ql_size,
			    int *out_offset, int head_pad_len)
{
	int aligned_size;
	int offset = *out_offset;
	unsigned long flags;
	int nr_of_skb = 0;

	while (pkt_to_send > 0) {
		/* Peek at the head of the list. */
		src_skb = skb_peek(ul_list);
		if (!src_skb) {
			dev_err(ipc_mux->dev,
				"skb peek return NULL with count : %d",
				pkt_to_send);
			return -1;
		}
		aligned_size = ALIGN((head_pad_len + src_skb->len), 4);
		ipc_mux->size_needed += sizeof(*dg) + aligned_size;

		if (ipc_mux->size_needed > adb->size ||
		    ((ipc_mux->size_needed + ipc_mux->ul_data_pend_bytes) >=
		      IPC_MEM_MUX_UL_FLOWCTRL_HIGH_B)) {
			*adb->next_table_index = offset;
			if (mux_ul_dg_update_tbl_index(ipc_mux, session_id,
						       ul_list, dg,
						       aligned_size,
						       qlth_n_ql_size, adb,
						       src_skb) < 0)
				return -ENOMEM;
			nr_of_skb = 0;
			offset = le32_to_cpu(adb->adbh->block_length);
			/* Load pointer to next available datagram entry */
			dg = adb->dg[session_id] + adb->dg_count[session_id];
		}
		/* Add buffer without head padding to next pending transfer. */
		memcpy(adb->buf + offset + head_pad_len,
		       src_skb->data, src_skb->len);
		/* Setup datagram entry. */
		dg->datagram_index = cpu_to_le32(offset);
		dg->datagram_length = cpu_to_le16(src_skb->len + head_pad_len);
		dg->service_class = (((struct sk_buff *)src_skb)->priority);
		dg->reserved = 0;
		adb->dg_cnt_total++;
		adb->payload_size += le16_to_cpu(dg->datagram_length);
		dg++;
		adb->dg_count[session_id]++;
		offset += aligned_size;
		/* Remove the processed elements and free it. */
		spin_lock_irqsave(&ul_list->lock, flags);
		src_skb = __skb_dequeue(ul_list);
		spin_unlock_irqrestore(&ul_list->lock, flags);

		dev_kfree_skb(src_skb);
		nr_of_skb++;
		pkt_to_send--;
	}
	*out_offset = offset;
	return nr_of_skb;
}

/* Process encode session UL data to ADB. */
static int mux_ul_adb_encode(struct iosm_mux *ipc_mux, int session_id,
			     struct mux_session *session,
			     struct sk_buff_head *ul_list, struct mux_adb *adb,
			     int pkt_to_send)
{
	int adb_updated = -EINVAL;
	int head_pad_len, offset;
	struct sk_buff *src_skb = NULL;
	struct mux_adth_dg *dg;
	u32 qlth_n_ql_size;

	/* If any of the opened session has set Flow Control ON then limit the
	 * UL data to mux_flow_ctrl_high_thresh_b bytes
	 */
	if (ipc_mux->ul_data_pend_bytes >=
		IPC_MEM_MUX_UL_FLOWCTRL_HIGH_B) {
		ipc_mux_stop_tx_for_all_sessions(ipc_mux);
		return adb_updated;
	}

	qlth_n_ql_size = offsetof(struct mux_qlth, ql) +
			 MUX_QUEUE_LEVEL * sizeof(struct mux_qlth_ql);
	head_pad_len = session->ul_head_pad_len;

	if (session->ul_head_pad_len > IPC_MEM_DL_ETH_OFFSET)
		head_pad_len = session->ul_head_pad_len - IPC_MEM_DL_ETH_OFFSET;

	if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed,
				    IOSM_AGGR_MUX_SIG_ADBH))
		return -ENOMEM;

	offset = le32_to_cpu(adb->adbh->block_length);

	if (ipc_mux->size_needed == 0)
		ipc_mux->size_needed = offset;

	/* Calculate the size needed for ADTH, QLTH and QL*/
	if (adb->dg_count[session_id] == 0) {
		ipc_mux->size_needed += offsetof(struct mux_adth, dg);
		ipc_mux->size_needed += qlth_n_ql_size;
	}

	dg = adb->dg[session_id] + adb->dg_count[session_id];

	if (mux_ul_dg_encode(ipc_mux, adb, dg, ul_list, src_skb,
			     session_id, pkt_to_send, qlth_n_ql_size, &offset,
			     head_pad_len) > 0) {
		adb_updated = 1;
		*adb->next_table_index = offset;
		ipc_mux_ul_adb_update_ql(ipc_mux, adb, session_id,
					 qlth_n_ql_size, ul_list);
		adb->adbh->block_length = cpu_to_le32(offset);
	}

	return adb_updated;
}

bool ipc_mux_ul_data_encode(struct iosm_mux *ipc_mux)
{
	struct sk_buff_head *ul_list;
	struct mux_session *session;
	int updated = 0;
	int session_id;
	int dg_n;
	int i;

	if (!ipc_mux || ipc_mux->state != MUX_S_ACTIVE ||
	    ipc_mux->adb_prep_ongoing)
		return false;

	ipc_mux->adb_prep_ongoing = true;

	for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++) {
		session_id = ipc_mux->rr_next_session;
		session = &ipc_mux->session[session_id];

		/* Go to next handle rr_next_session overflow */
		ipc_mux->rr_next_session++;
		if (ipc_mux->rr_next_session >= IPC_MEM_MUX_IP_SESSION_ENTRIES)
			ipc_mux->rr_next_session = 0;

		if (!session->wwan || session->flow_ctl_mask ||
		    session->net_tx_stop)
			continue;

		ul_list = &session->ul_list;

		/* Is something pending in UL and flow ctrl off */
		dg_n = skb_queue_len(ul_list);
		if (dg_n > MUX_MAX_UL_DG_ENTRIES)
			dg_n = MUX_MAX_UL_DG_ENTRIES;

		if (dg_n == 0)
			/* Nothing to do for ipc_mux session
			 * -> try next session id.
			 */
			continue;
		if (ipc_mux->protocol == MUX_LITE)
			updated = ipc_mux_ul_adgh_encode(ipc_mux, session_id,
							 session, ul_list,
							 &ipc_mux->ul_adb,
							 dg_n);
		else
			updated = mux_ul_adb_encode(ipc_mux, session_id,
						    session, ul_list,
						    &ipc_mux->ul_adb,
						    dg_n);
	}

	ipc_mux->adb_prep_ongoing = false;
	return updated == 1;
}

/* Calculates the Payload from any given ADB. */
static int ipc_mux_get_payload_from_adb(struct iosm_mux *ipc_mux,
					struct mux_adbh *p_adbh)
{
	struct mux_adth_dg *dg;
	struct mux_adth *adth;
	u32 payload_size = 0;
	u32 next_table_idx;
	int nr_of_dg, i;

	/* Process the aggregated datagram tables. */
	next_table_idx = le32_to_cpu(p_adbh->first_table_index);

	if (next_table_idx < sizeof(struct mux_adbh)) {
		dev_err(ipc_mux->dev, "unexpected empty ADB");
		return payload_size;
	}

	while (next_table_idx != 0) {
		/* Get the reference to the table header. */
		adth = (struct mux_adth *)((u8 *)p_adbh + next_table_idx);

		if (adth->signature == cpu_to_le32(IOSM_AGGR_MUX_SIG_ADTH)) {
			nr_of_dg = (le16_to_cpu(adth->table_length) -
					sizeof(struct mux_adth) +
					sizeof(struct mux_adth_dg)) /
					sizeof(struct mux_adth_dg);

			if (nr_of_dg <= 0)
				return payload_size;

			dg = &adth->dg;

			for (i = 0; i < nr_of_dg; i++, dg++) {
				if (le32_to_cpu(dg->datagram_index) <
					sizeof(struct mux_adbh)) {
					return payload_size;
				}
				payload_size +=
					le16_to_cpu(dg->datagram_length);
			}
		}
		next_table_idx = le32_to_cpu(adth->next_table_index);
	}

	return payload_size;
}

void ipc_mux_ul_encoded_process(struct iosm_mux *ipc_mux, struct sk_buff *skb)
{
	union mux_type_header hr;
	u16 adgh_len;
	int payload;

	if (ipc_mux->protocol == MUX_LITE) {
		hr.adgh = (struct mux_adgh *)skb->data;
		adgh_len = le16_to_cpu(hr.adgh->length);
		if (hr.adgh->signature == cpu_to_le32(IOSM_AGGR_MUX_SIG_ADGH) &&
		    ipc_mux->ul_flow == MUX_UL)
			ipc_mux->ul_data_pend_bytes =
					ipc_mux->ul_data_pend_bytes - adgh_len;
	} else {
		hr.adbh = (struct mux_adbh *)(skb->data);
		payload = ipc_mux_get_payload_from_adb(ipc_mux, hr.adbh);
		ipc_mux->ul_data_pend_bytes -= payload;
	}

	if (ipc_mux->ul_flow == MUX_UL)
		dev_dbg(ipc_mux->dev, "ul_data_pend_bytes: %lld",
			ipc_mux->ul_data_pend_bytes);

	/* Reset the skb settings. */
	skb_trim(skb, 0);

	/* Add the consumed ADB to the free list. */
	skb_queue_tail((&ipc_mux->ul_adb.free_list), skb);
}

/* Start the NETIF uplink send transfer in MUX mode. */
static int ipc_mux_tq_ul_trigger_encode(struct iosm_imem *ipc_imem, int arg,
					void *msg, size_t size)
{
	struct iosm_mux *ipc_mux = ipc_imem->mux;
	bool ul_data_pend = false;

	/* Add session UL data to a ADB and ADGH */
	ul_data_pend = ipc_mux_ul_data_encode(ipc_mux);
	if (ul_data_pend) {
		if (ipc_mux->protocol == MUX_AGGREGATION)
			ipc_imem_adb_timer_start(ipc_mux->imem);

		/* Delay the doorbell irq */
		ipc_imem_td_update_timer_start(ipc_mux->imem);
	}
	/* reset the debounce flag */
	ipc_mux->ev_mux_net_transmit_pending = false;

	return 0;
}

int ipc_mux_ul_trigger_encode(struct iosm_mux *ipc_mux, int if_id,
			      struct sk_buff *skb)
{
	struct mux_session *session = &ipc_mux->session[if_id];
	int ret = -EINVAL;

	if (ipc_mux->channel &&
	    ipc_mux->channel->state != IMEM_CHANNEL_ACTIVE) {
		dev_err(ipc_mux->dev,
			"channel state is not IMEM_CHANNEL_ACTIVE");
		goto out;
	}

	if (!session->wwan) {
		dev_err(ipc_mux->dev, "session net ID is NULL");
		ret = -EFAULT;
		goto out;
	}

	/* Session is under flow control.
	 * Check if packet can be queued in session list, if not
	 * suspend net tx
	 */
	if (skb_queue_len(&session->ul_list) >=
	    (session->net_tx_stop ?
		     IPC_MEM_MUX_UL_SESS_FCON_THRESHOLD :
		     (IPC_MEM_MUX_UL_SESS_FCON_THRESHOLD *
		      IPC_MEM_MUX_UL_SESS_FCOFF_THRESHOLD_FACTOR))) {
		ipc_mux_netif_tx_flowctrl(session, session->if_id, true);
		ret = -EBUSY;
		goto out;
	}

	/* Add skb to the uplink skb accumulator. */
	skb_queue_tail(&session->ul_list, skb);

	/* Inform the IPC kthread to pass uplink IP packets to CP. */
	if (!ipc_mux->ev_mux_net_transmit_pending) {
		ipc_mux->ev_mux_net_transmit_pending = true;
		ret = ipc_task_queue_send_task(ipc_mux->imem,
					       ipc_mux_tq_ul_trigger_encode, 0,
					       NULL, 0, false);
		if (ret)
			goto out;
	}
	dev_dbg(ipc_mux->dev, "mux ul if[%d] qlen=%d/%u, len=%d/%d, prio=%d",
		if_id, skb_queue_len(&session->ul_list), session->ul_list.qlen,
		skb->len, skb->truesize, skb->priority);
	ret = 0;
out:
	return ret;
}
