// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *
 * Contributors:
 *  Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 *  Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
 *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
 *  Eliot Lee <eliot.lee@intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 */

#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/wwan.h>

#include "t7xx_hif_cldma.h"
#include "t7xx_modem_ops.h"
#include "t7xx_port.h"
#include "t7xx_port_proxy.h"
#include "t7xx_state_monitor.h"

#define Q_IDX_CTRL			0
#define Q_IDX_MBIM			2
#define Q_IDX_AT_CMD			5

#define INVALID_SEQ_NUM			GENMASK(15, 0)

#define for_each_proxy_port(i, p, proxy)	\
	for (i = 0, (p) = &(proxy)->ports[i];	\
	     i < (proxy)->port_count;		\
	     i++, (p) = &(proxy)->ports[i])

static const struct t7xx_port_conf t7xx_port_conf[] = {
	{
		.tx_ch = PORT_CH_UART2_TX,
		.rx_ch = PORT_CH_UART2_RX,
		.txq_index = Q_IDX_AT_CMD,
		.rxq_index = Q_IDX_AT_CMD,
		.txq_exp_index = 0xff,
		.rxq_exp_index = 0xff,
		.path_id = CLDMA_ID_MD,
		.ops = &wwan_sub_port_ops,
		.name = "AT",
		.port_type = WWAN_PORT_AT,
	}, {
		.tx_ch = PORT_CH_MBIM_TX,
		.rx_ch = PORT_CH_MBIM_RX,
		.txq_index = Q_IDX_MBIM,
		.rxq_index = Q_IDX_MBIM,
		.path_id = CLDMA_ID_MD,
		.ops = &wwan_sub_port_ops,
		.name = "MBIM",
		.port_type = WWAN_PORT_MBIM,
	}, {
#ifdef CONFIG_WWAN_DEBUGFS
		.tx_ch = PORT_CH_MD_LOG_TX,
		.rx_ch = PORT_CH_MD_LOG_RX,
		.txq_index = 7,
		.rxq_index = 7,
		.txq_exp_index = 7,
		.rxq_exp_index = 7,
		.path_id = CLDMA_ID_MD,
		.ops = &t7xx_trace_port_ops,
		.name = "mdlog",
	}, {
#endif
		.tx_ch = PORT_CH_CONTROL_TX,
		.rx_ch = PORT_CH_CONTROL_RX,
		.txq_index = Q_IDX_CTRL,
		.rxq_index = Q_IDX_CTRL,
		.path_id = CLDMA_ID_MD,
		.ops = &ctl_port_ops,
		.name = "t7xx_ctrl",
	}, {
		.tx_ch = PORT_CH_AP_CONTROL_TX,
		.rx_ch = PORT_CH_AP_CONTROL_RX,
		.txq_index = Q_IDX_CTRL,
		.rxq_index = Q_IDX_CTRL,
		.path_id = CLDMA_ID_AP,
		.ops = &ctl_port_ops,
		.name = "t7xx_ap_ctrl",
	},
};

static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch)
{
	const struct t7xx_port_conf *port_conf;
	struct t7xx_port *port;
	int i;

	for_each_proxy_port(i, port, port_prox) {
		port_conf = port->port_conf;
		if (port_conf->rx_ch == ch || port_conf->tx_ch == ch)
			return port;
	}

	return NULL;
}

static u16 t7xx_port_next_rx_seq_num(struct t7xx_port *port, struct ccci_header *ccci_h)
{
	u32 status = le32_to_cpu(ccci_h->status);
	u16 seq_num, next_seq_num;
	bool assert_bit;

	seq_num = FIELD_GET(CCCI_H_SEQ_FLD, status);
	next_seq_num = (seq_num + 1) & FIELD_MAX(CCCI_H_SEQ_FLD);
	assert_bit = status & CCCI_H_AST_BIT;
	if (!assert_bit || port->seq_nums[MTK_RX] == INVALID_SEQ_NUM)
		return next_seq_num;

	if (seq_num != port->seq_nums[MTK_RX])
		dev_warn_ratelimited(port->dev,
				     "seq num out-of-order %u != %u (header %X, len %X)\n",
				     seq_num, port->seq_nums[MTK_RX],
				     le32_to_cpu(ccci_h->packet_header),
				     le32_to_cpu(ccci_h->packet_len));

	return next_seq_num;
}

void t7xx_port_proxy_reset(struct port_proxy *port_prox)
{
	struct t7xx_port *port;
	int i;

	for_each_proxy_port(i, port, port_prox) {
		port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
		port->seq_nums[MTK_TX] = 0;
	}
}

static int t7xx_port_get_queue_no(struct t7xx_port *port)
{
	const struct t7xx_port_conf *port_conf = port->port_conf;
	struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;

	return t7xx_fsm_get_md_state(ctl) == MD_STATE_EXCEPTION ?
		port_conf->txq_exp_index : port_conf->txq_index;
}

static void t7xx_port_struct_init(struct t7xx_port *port)
{
	INIT_LIST_HEAD(&port->entry);
	INIT_LIST_HEAD(&port->queue_entry);
	skb_queue_head_init(&port->rx_skb_list);
	init_waitqueue_head(&port->rx_wq);
	port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
	port->seq_nums[MTK_TX] = 0;
	atomic_set(&port->usage_cnt, 0);
}

struct sk_buff *t7xx_port_alloc_skb(int payload)
{
	struct sk_buff *skb = __dev_alloc_skb(payload + sizeof(struct ccci_header), GFP_KERNEL);

	if (skb)
		skb_reserve(skb, sizeof(struct ccci_header));

	return skb;
}

struct sk_buff *t7xx_ctrl_alloc_skb(int payload)
{
	struct sk_buff *skb = t7xx_port_alloc_skb(payload + sizeof(struct ctrl_msg_header));

	if (skb)
		skb_reserve(skb, sizeof(struct ctrl_msg_header));

	return skb;
}

/**
 * t7xx_port_enqueue_skb() - Enqueue the received skb into the port's rx_skb_list.
 * @port: port context.
 * @skb: received skb.
 *
 * Return:
 * * 0		- Success.
 * * -ENOBUFS	- Not enough buffer space. Caller will try again later, skb is not consumed.
 */
int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
{
	unsigned long flags;

	spin_lock_irqsave(&port->rx_wq.lock, flags);
	if (port->rx_skb_list.qlen >= port->rx_length_th) {
		spin_unlock_irqrestore(&port->rx_wq.lock, flags);

		return -ENOBUFS;
	}
	__skb_queue_tail(&port->rx_skb_list, skb);
	spin_unlock_irqrestore(&port->rx_wq.lock, flags);

	wake_up_all(&port->rx_wq);
	return 0;
}

static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
{
	enum cldma_id path_id = port->port_conf->path_id;
	struct cldma_ctrl *md_ctrl;
	int ret, tx_qno;

	md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
	tx_qno = t7xx_port_get_queue_no(port);
	ret = t7xx_cldma_send_skb(md_ctrl, tx_qno, skb);
	if (ret)
		dev_err(port->dev, "Failed to send skb: %d\n", ret);

	return ret;
}

static int t7xx_port_send_ccci_skb(struct t7xx_port *port, struct sk_buff *skb,
				   unsigned int pkt_header, unsigned int ex_msg)
{
	const struct t7xx_port_conf *port_conf = port->port_conf;
	struct ccci_header *ccci_h;
	u32 status;
	int ret;

	ccci_h = skb_push(skb, sizeof(*ccci_h));
	status = FIELD_PREP(CCCI_H_CHN_FLD, port_conf->tx_ch) |
		 FIELD_PREP(CCCI_H_SEQ_FLD, port->seq_nums[MTK_TX]) | CCCI_H_AST_BIT;
	ccci_h->status = cpu_to_le32(status);
	ccci_h->packet_header = cpu_to_le32(pkt_header);
	ccci_h->packet_len = cpu_to_le32(skb->len);
	ccci_h->ex_msg = cpu_to_le32(ex_msg);

	ret = t7xx_port_send_raw_skb(port, skb);
	if (ret)
		return ret;

	port->seq_nums[MTK_TX]++;
	return 0;
}

int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
			   unsigned int ex_msg)
{
	struct ctrl_msg_header *ctrl_msg_h;
	unsigned int msg_len = skb->len;
	u32 pkt_header = 0;

	ctrl_msg_h = skb_push(skb, sizeof(*ctrl_msg_h));
	ctrl_msg_h->ctrl_msg_id = cpu_to_le32(msg);
	ctrl_msg_h->ex_msg = cpu_to_le32(ex_msg);
	ctrl_msg_h->data_length = cpu_to_le32(msg_len);

	if (!msg_len)
		pkt_header = CCCI_HEADER_NO_DATA;

	return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
}

int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
		       unsigned int ex_msg)
{
	struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;
	unsigned int fsm_state;

	fsm_state = t7xx_fsm_get_ctl_state(ctl);
	if (fsm_state != FSM_STATE_PRE_START) {
		const struct t7xx_port_conf *port_conf = port->port_conf;
		enum md_state md_state = t7xx_fsm_get_md_state(ctl);

		switch (md_state) {
		case MD_STATE_EXCEPTION:
			if (port_conf->tx_ch != PORT_CH_MD_LOG_TX)
				return -EBUSY;
			break;

		case MD_STATE_WAITING_FOR_HS1:
		case MD_STATE_WAITING_FOR_HS2:
		case MD_STATE_STOPPED:
		case MD_STATE_WAITING_TO_STOP:
		case MD_STATE_INVALID:
			return -ENODEV;

		default:
			break;
		}
	}

	return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
}

static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
{
	struct t7xx_port *port;

	int i, j;

	for (i = 0; i < ARRAY_SIZE(port_prox->rx_ch_ports); i++)
		INIT_LIST_HEAD(&port_prox->rx_ch_ports[i]);

	for (j = 0; j < ARRAY_SIZE(port_prox->queue_ports); j++) {
		for (i = 0; i < ARRAY_SIZE(port_prox->queue_ports[j]); i++)
			INIT_LIST_HEAD(&port_prox->queue_ports[j][i]);
	}

	for_each_proxy_port(i, port, port_prox) {
		const struct t7xx_port_conf *port_conf = port->port_conf;
		enum cldma_id path_id = port_conf->path_id;
		u8 ch_id;

		ch_id = FIELD_GET(PORT_CH_ID_MASK, port_conf->rx_ch);
		list_add_tail(&port->entry, &port_prox->rx_ch_ports[ch_id]);
		list_add_tail(&port->queue_entry,
			      &port_prox->queue_ports[path_id][port_conf->rxq_index]);
	}
}

static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev,
						   struct cldma_queue *queue, u16 channel)
{
	struct port_proxy *port_prox = t7xx_dev->md->port_prox;
	struct list_head *port_list;
	struct t7xx_port *port;
	u8 ch_id;

	ch_id = FIELD_GET(PORT_CH_ID_MASK, channel);
	port_list = &port_prox->rx_ch_ports[ch_id];
	list_for_each_entry(port, port_list, entry) {
		const struct t7xx_port_conf *port_conf = port->port_conf;

		if (queue->md_ctrl->hif_id == port_conf->path_id &&
		    channel == port_conf->rx_ch)
			return port;
	}

	return NULL;
}

/**
 * t7xx_port_proxy_recv_skb() - Dispatch received skb.
 * @queue: CLDMA queue.
 * @skb: Socket buffer.
 *
 * Return:
 ** 0		- Packet consumed.
 ** -ERROR	- Failed to process skb.
 */
static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb)
{
	struct ccci_header *ccci_h = (struct ccci_header *)skb->data;
	struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
	struct t7xx_fsm_ctl *ctl = t7xx_dev->md->fsm_ctl;
	struct device *dev = queue->md_ctrl->dev;
	const struct t7xx_port_conf *port_conf;
	struct t7xx_port *port;
	u16 seq_num, channel;
	int ret;

	channel = FIELD_GET(CCCI_H_CHN_FLD, le32_to_cpu(ccci_h->status));
	if (t7xx_fsm_get_md_state(ctl) == MD_STATE_INVALID) {
		dev_err_ratelimited(dev, "Packet drop on channel 0x%x, modem not ready\n", channel);
		goto drop_skb;
	}

	port = t7xx_port_proxy_find_port(t7xx_dev, queue, channel);
	if (!port) {
		dev_err_ratelimited(dev, "Packet drop on channel 0x%x, port not found\n", channel);
		goto drop_skb;
	}

	seq_num = t7xx_port_next_rx_seq_num(port, ccci_h);
	port_conf = port->port_conf;
	skb_pull(skb, sizeof(*ccci_h));

	ret = port_conf->ops->recv_skb(port, skb);
	/* Error indicates to try again later */
	if (ret) {
		skb_push(skb, sizeof(*ccci_h));
		return ret;
	}

	port->seq_nums[MTK_RX] = seq_num;
	return 0;

drop_skb:
	dev_kfree_skb_any(skb);
	return 0;
}

/**
 * t7xx_port_proxy_md_status_notify() - Notify all ports of state.
 *@port_prox: The port_proxy pointer.
 *@state: State.
 *
 * Called by t7xx_fsm. Used to dispatch modem status for all ports,
 * which want to know MD state transition.
 */
void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int state)
{
	struct t7xx_port *port;
	int i;

	for_each_proxy_port(i, port, port_prox) {
		const struct t7xx_port_conf *port_conf = port->port_conf;

		if (port_conf->ops->md_state_notify)
			port_conf->ops->md_state_notify(port, state);
	}
}

static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
{
	struct port_proxy *port_prox = md->port_prox;
	struct t7xx_port *port;
	int i;

	for_each_proxy_port(i, port, port_prox) {
		const struct t7xx_port_conf *port_conf = port->port_conf;

		t7xx_port_struct_init(port);

		if (port_conf->tx_ch == PORT_CH_CONTROL_TX)
			md->core_md.ctl_port = port;

		if (port_conf->tx_ch == PORT_CH_AP_CONTROL_TX)
			md->core_ap.ctl_port = port;

		port->t7xx_dev = md->t7xx_dev;
		port->dev = &md->t7xx_dev->pdev->dev;
		spin_lock_init(&port->port_update_lock);
		port->chan_enable = false;

		if (port_conf->ops->init)
			port_conf->ops->init(port);
	}

	t7xx_proxy_setup_ch_mapping(port_prox);
}

static int t7xx_proxy_alloc(struct t7xx_modem *md)
{
	unsigned int port_count = ARRAY_SIZE(t7xx_port_conf);
	struct device *dev = &md->t7xx_dev->pdev->dev;
	struct port_proxy *port_prox;
	int i;

	port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * port_count,
				 GFP_KERNEL);
	if (!port_prox)
		return -ENOMEM;

	md->port_prox = port_prox;
	port_prox->dev = dev;

	for (i = 0; i < port_count; i++)
		port_prox->ports[i].port_conf = &t7xx_port_conf[i];

	port_prox->port_count = port_count;
	t7xx_proxy_init_all_ports(md);
	return 0;
}

/**
 * t7xx_port_proxy_init() - Initialize ports.
 * @md: Modem.
 *
 * Create all port instances.
 *
 * Return:
 * * 0		- Success.
 * * -ERROR	- Error code from failure sub-initializations.
 */
int t7xx_port_proxy_init(struct t7xx_modem *md)
{
	int ret;

	ret = t7xx_proxy_alloc(md);
	if (ret)
		return ret;

	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_AP], t7xx_port_proxy_recv_skb);
	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb);
	return 0;
}

void t7xx_port_proxy_uninit(struct port_proxy *port_prox)
{
	struct t7xx_port *port;
	int i;

	for_each_proxy_port(i, port, port_prox) {
		const struct t7xx_port_conf *port_conf = port->port_conf;

		if (port_conf->ops->uninit)
			port_conf->ops->uninit(port);
	}
}

int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id,
				       bool en_flag)
{
	struct t7xx_port *port = t7xx_proxy_get_port_by_ch(port_prox, ch_id);
	const struct t7xx_port_conf *port_conf;

	if (!port)
		return -EINVAL;

	port_conf = port->port_conf;

	if (en_flag) {
		if (port_conf->ops->enable_chl)
			port_conf->ops->enable_chl(port);
	} else {
		if (port_conf->ops->disable_chl)
			port_conf->ops->disable_chl(port);
	}

	return 0;
}
