/*
 **************************************************************************
 * Copyright (c) 2014-2017, 2019-2020, The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **************************************************************************
 */

#include "nss_qdisc.h"

/*
 * nssprio qdisc instance structure
 */
struct nss_prio_sched_data {
	struct nss_qdisc nq;	/* Common base class for all nss qdiscs */
	int bands;		/* Number of priority bands to use */
	struct Qdisc *queues[TCA_NSSPRIO_MAX_BANDS];
				/* Array of child qdisc holder */
};

/*
 * nssprio policy structure
 */
static struct nla_policy nss_prio_policy[TCA_NSSPRIO_MAX + 1] = {
	[TCA_NSSPRIO_PARMS] = { .len = sizeof(struct tc_nssprio_qopt) },
};

/*
 * nss_prio_enqueue()
 *	Enqueues a skb to nssprio qdisc.
 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
static int nss_prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
#else
static int nss_prio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
				struct sk_buff **to_free)
#endif
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
	return nss_qdisc_enqueue(skb, sch);
#else
	return nss_qdisc_enqueue(skb, sch, to_free);
#endif
}

/*
 * nss_prio_dequeue()
 *	Dequeues a skb to nssprio qdisc.
 */
static struct sk_buff *nss_prio_dequeue(struct Qdisc *sch)
{
	return nss_qdisc_dequeue(sch);
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
/*
 * nss_prio_drop()
 *	Drops a single skb from linux queue, if not empty.
 *
 * Does not drop packets that are queued in the NSS.
 */
static unsigned int nss_prio_drop(struct Qdisc *sch)
{
	return nss_qdisc_drop(sch);
}
#endif

/*
 * nss_prio_peek()
 *	Peeks the first packet in queue for this qdisc.
 */
static struct sk_buff *nss_prio_peek(struct Qdisc *sch)
{
	return nss_qdisc_peek(sch);
}

/*
 * nss_prio_reset()
 *	Reset the nssprio qdisc
 */
static void nss_prio_reset(struct Qdisc *sch)
{
	return nss_qdisc_reset(sch);
}

/*
 * nss_prio_destroy()
 *	Destroy the nssprio qdisc
 */
static void nss_prio_destroy(struct Qdisc *sch)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	struct nss_if_msg nim;
	int i;

	nss_qdisc_info("Destroying prio");

	/*
	 * Destroy all attached child nodes before destroying prio
	 */
	for (i = 0; i < q->bands; i++) {

		/*
		 * We always detach the shaper in NSS before destroying it.
		 * It is very important to check for noop qdisc since those dont
		 * exist in the NSS.
		 */
		if (q->queues[i] != &noop_qdisc) {
			struct nss_qdisc *nq_child = qdisc_priv(q->queues[i]);
			nim.msg.shaper_configure.config.msg.shaper_node_config.qos_tag = q->nq.qos_tag;
			nim.msg.shaper_configure.config.msg.shaper_node_config.snc.prio_detach.priority = i;
			if (nss_qdisc_node_detach(&q->nq, nq_child, &nim,
					NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_DETACH) < 0) {
				nss_qdisc_error("Failed to detach child in band %d from prio %x\n",
							i, q->nq.qos_tag);
				return;
			}
		}

		/*
		 * We can now destroy it
		 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0))
		qdisc_destroy(q->queues[i]);
#else
		qdisc_put(q->queues[i]);
#endif
	}

	/*
	 * Stop the polling of basic stats
	 */
	nss_qdisc_stop_basic_stats_polling(&q->nq);

	/*
	 * Destroy the qdisc in NSS
	 */
	nss_qdisc_destroy(&q->nq);
}

/*
 * nss_prio_get_max_bands()
 *	Function call to get max bamds supported
 */
static int nss_prio_get_max_bands(struct Qdisc *sch)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	q = qdisc_priv(sch);

#if defined(NSS_QDISC_PPE_SUPPORT)
	if (q->nq.mode == NSS_QDISC_MODE_PPE) {
		return nss_ppe_get_max_prio_bands(&q->nq);
	}
#endif

	if (q->nq.mode == NSS_QDISC_MODE_NSS) {
		return TCA_NSSPRIO_MAX_BANDS;
	}

	return 0;
}

/*
 * nss_prio_change()
 *	Function call to configure the nssprio parameters
 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
static int nss_prio_change(struct Qdisc *sch, struct nlattr *opt)
#else
static int nss_prio_change(struct Qdisc *sch, struct nlattr *opt,
				struct netlink_ext_ack *extack)
#endif
{
	struct nlattr *tb[TCA_NSSPRIO_MAX + 1];
	struct nss_prio_sched_data *q;
	struct tc_nssprio_qopt *qopt;

	q = qdisc_priv(sch);

	/*
	 * Since nssprio can be created with no arguments, opt might be NULL
	 * (depending on the kernel version). This is still a valid create
	 * request.
	 */
	if (!opt) {

		/*
		 * If no parameter is passed, set it to the default value.
		 */
		sch_tree_lock(sch);
		q->bands = TCA_NSSPRIO_MAX_BANDS;
		sch_tree_unlock(sch);
		return 0;
	}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
	qopt = nss_qdisc_qopt_get(opt, nss_prio_policy, tb, TCA_NSSPRIO_MAX, TCA_NSSPRIO_PARMS);
#else
	qopt = nss_qdisc_qopt_get(opt, nss_prio_policy, tb, TCA_NSSPRIO_MAX, TCA_NSSPRIO_PARMS, extack);
#endif
	if (!qopt) {
		return -EINVAL;
	}

	if (qopt->bands > nss_prio_get_max_bands(sch)) {
		nss_qdisc_warning("nssprio (accel_mode %d) requires max bands to be %d\n",
				nss_qdisc_accel_mode_get(&q->nq), nss_prio_get_max_bands(sch));
		return -EINVAL;
	}

	sch_tree_lock(sch);
	q->bands = qopt->bands;
	sch_tree_unlock(sch);
	nss_qdisc_info("Bands = %u\n", qopt->bands);

	/*
	 * We do not pass on this information to NSS since
	 * it not required for operation of prio. This parameter
	 * is needed only for the proxy operation.
	 */

	return 0;
}

/*
 * nss_prio_init()
 *	Initializes the nssprio qdisc
 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
static int nss_prio_init(struct Qdisc *sch, struct nlattr *opt)
{
	struct netlink_ext_ack *extack = NULL;
#else
static int nss_prio_init(struct Qdisc *sch, struct nlattr *opt,
				struct netlink_ext_ack *extack)
{
#endif
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	struct nlattr *tb[TCA_NSSPRIO_MAX + 1];
	struct tc_nssprio_qopt *qopt;
	int i;
	unsigned int accel_mode;

	for (i = 0; i < TCA_NSSPRIO_MAX_BANDS; i++) {
		q->queues[i] = &noop_qdisc;
	}

	if (!opt) {
		accel_mode = TCA_NSS_ACCEL_MODE_PPE;
	} else {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
		qopt = nss_qdisc_qopt_get(opt, nss_prio_policy, tb, TCA_NSSPRIO_MAX, TCA_NSSPRIO_PARMS);
#else
		qopt = nss_qdisc_qopt_get(opt, nss_prio_policy, tb, TCA_NSSPRIO_MAX, TCA_NSSPRIO_PARMS, extack);
#endif
		if (!qopt) {
			return -EINVAL;
		}
		accel_mode = qopt->accel_mode;
	}

	if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_PRIO, 0, accel_mode, extack) < 0)
	{
		return -EINVAL;
	}

	nss_qdisc_info("Nssprio initialized - handle %x parent %x\n",
			sch->handle, sch->parent);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
	if (nss_prio_change(sch, opt) < 0) {
#else
	if (nss_prio_change(sch, opt, extack) < 0) {
#endif
		nss_qdisc_destroy(&q->nq);
		return -EINVAL;
	}

	/*
	 * Start the stats polling timer
	 */
	nss_qdisc_start_basic_stats_polling(&q->nq);
	return 0;
}

/*
 * nss_prio_dump()
 *	Dump the parameters of nssprio
 */
static int nss_prio_dump(struct Qdisc *sch, struct sk_buff *skb)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	struct nlattr *opts = NULL;
	struct tc_nssprio_qopt qopt;

	nss_qdisc_info("Nssprio dumping");
	qopt.bands = q->bands;
	qopt.accel_mode = nss_qdisc_accel_mode_get(&q->nq);

	opts = nss_qdisc_nla_nest_start(skb, TCA_OPTIONS);
	if (opts == NULL || nla_put(skb, TCA_NSSPRIO_PARMS, sizeof(qopt), &qopt)) {
		goto nla_put_failure;
	}

	return nla_nest_end(skb, opts);

nla_put_failure:
	nla_nest_cancel(skb, opts);
	return -EMSGSIZE;
}

/*
 * nss_prio_graft()
 *	Replaces existing child qdisc with the new qdisc that is passed.
 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
static int nss_prio_graft(struct Qdisc *sch, unsigned long arg,
				struct Qdisc *new, struct Qdisc **old)
#else
static int nss_prio_graft(struct Qdisc *sch, unsigned long arg,
				struct Qdisc *new, struct Qdisc **old,
				struct netlink_ext_ack *extack)
#endif
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	struct nss_qdisc *nq_new = qdisc_priv(new);
	uint32_t band = (uint32_t)(arg - 1);
	struct nss_if_msg nim_attach;
	struct nss_if_msg nim_detach;

	nss_qdisc_info("Grafting band %u, available bands %u\n", band, q->bands);

	if (new == NULL)
		new = &noop_qdisc;

	if (band > q->bands)
		return -EINVAL;

	sch_tree_lock(sch);
	*old = q->queues[band];
	sch_tree_unlock(sch);

	nss_qdisc_info("Grafting old: %px with new: %px\n", *old, new);
	if (*old != &noop_qdisc) {
		struct nss_qdisc *nq_old = qdisc_priv(*old);
		nss_qdisc_info("Detaching old: %px\n", *old);
		nim_detach.msg.shaper_configure.config.msg.shaper_node_config.qos_tag = q->nq.qos_tag;

		if (q->nq.mode == NSS_QDISC_MODE_NSS) {
			nim_detach.msg.shaper_configure.config.msg.shaper_node_config.snc.prio_detach.priority = band;
		}

		if (nss_qdisc_node_detach(&q->nq, nq_old, &nim_detach,
				NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_DETACH) < 0) {
			return -EINVAL;
		}
	}

	if (new != &noop_qdisc) {
		nss_qdisc_info("Attaching new child with qos tag: %x, priority: %u to "
				"qos_tag: %x\n", nq_new->qos_tag, band, q->nq.qos_tag);
		nim_attach.msg.shaper_configure.config.msg.shaper_node_config.qos_tag = q->nq.qos_tag;
		nim_attach.msg.shaper_configure.config.msg.shaper_node_config.snc.prio_attach.child_qos_tag = nq_new->qos_tag;

#if defined(NSS_QDISC_PPE_SUPPORT)
		if (q->nq.mode == NSS_QDISC_MODE_PPE) {
			nq_new->npq.scheduler.priority = band;
		}
#endif

		if (q->nq.mode == NSS_QDISC_MODE_NSS) {
			nim_attach.msg.shaper_configure.config.msg.shaper_node_config.snc.prio_attach.priority = band;
		}

		if (nss_qdisc_node_attach(&q->nq, nq_new, &nim_attach,
				NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_ATTACH) < 0) {
			return -EINVAL;
		}
	}

	/*
	 * Replaced in NSS, now replace in Linux.
	 */
	nss_qdisc_replace(sch, new, &q->queues[band]);

	nss_qdisc_info("Nssprio grafted");

	return 0;
}

/*
 * nss_prio_leaf_class()
 *	Returns pointer to qdisc if leaf class.
 */
static struct Qdisc *nss_prio_leaf(struct Qdisc *sch, unsigned long arg)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	uint32_t band = (uint32_t)(arg - 1);

	nss_qdisc_info("Nssprio returns leaf\n");

	if (band > q->bands)
		return NULL;

	return q->queues[band];
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
/*
 * nss_prio_get()
 *	Returns the band if provided the classid.
 */
static unsigned long nss_prio_get(struct Qdisc *sch, u32 classid)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	unsigned long band = TC_H_MIN(classid);

	nss_qdisc_info("Inside get. Handle - %x Classid - %x Band %lu Available band %u\n", sch->handle, classid, band, q->bands);

	if (band > q->bands)
		return 0;

	return band;
}

/*
 * nss_prio_put()
 *	Unused API.
 */
static void nss_prio_put(struct Qdisc *sch, unsigned long arg)
{
	nss_qdisc_info("Inside prio put\n");
}
#else
/*
 * nss_prio_search()
 *	Returns the band if provided the classid.
 */
static unsigned long nss_prio_search(struct Qdisc *sch, u32 classid)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	unsigned long band = TC_H_MIN(classid);

	nss_qdisc_info("Inside get. Handle - %x Classid - %x Band %lu Available band %u\n", sch->handle, classid, band, q->bands);

	if (band > q->bands)
		return 0;

	return band;
}
#endif

/*
 * nss_prio_walk()
 *	Walks the priority band.
 */
static void nss_prio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	int i;

	if (arg->stop)
		return;

	for (i = 0; i < q->bands; i++) {
		if (arg->count < arg->skip) {
			arg->count++;
			continue;
		}
		if (arg->fn(sch, i + 1, arg) < 0) {
			arg->stop = 1;
			break;
		}
		arg->count++;
	}
	nss_qdisc_info("Nssprio walk called\n");
}

/*
 * nss_prio_dump_class()
 * 	Dumps all configurable parameters pertaining to this class.
 */
static int nss_prio_dump_class(struct Qdisc *sch, unsigned long cl,
			     struct sk_buff *skb, struct tcmsg *tcm)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);

	tcm->tcm_handle |= TC_H_MIN(cl);
	tcm->tcm_info = q->queues[cl - 1]->handle;

	nss_qdisc_info("Nssprio dumping class\n");
	return 0;
}

/*
 * nss_prio_dump_class_stats()
 *	Dumps class statistics.
 */
static int nss_prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
			     	    struct gnet_dump *d)
{
	struct nss_prio_sched_data *q = qdisc_priv(sch);
	struct Qdisc *cl_q;

	cl_q = q->queues[cl - 1];
	cl_q->qstats.qlen = cl_q->q.qlen;

	if (nss_qdisc_gnet_stats_copy_basic(sch, d, &cl_q->bstats) < 0 ||
			nss_qdisc_gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
		return -1;

	nss_qdisc_info("Nssprio dumping class stats\n");
	return 0;
}

/*
 * Registration structure for nssprio class
 */
const struct Qdisc_class_ops nss_prio_class_ops = {
	.graft		=	nss_prio_graft,
	.leaf		=	nss_prio_leaf,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
	.get		=	nss_prio_get,
	.put		=	nss_prio_put,
#else
	.find       =   nss_prio_search,
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
	.tcf_chain	=	nss_qdisc_tcf_chain,
#else
	.tcf_block	=	nss_qdisc_tcf_block,
#endif
	.bind_tcf	=	nss_qdisc_tcf_bind,
	.unbind_tcf	=	nss_qdisc_tcf_unbind,
	.walk		=	nss_prio_walk,
	.dump		=	nss_prio_dump_class,
	.dump_stats	=	nss_prio_dump_class_stats,
};

/*
 * Registration structure for nssprio qdisc
 */
struct Qdisc_ops nss_prio_qdisc_ops __read_mostly = {
	.next		=	NULL,
	.id		=	"nssprio",
	.priv_size	=	sizeof(struct nss_prio_sched_data),
	.cl_ops		=	&nss_prio_class_ops,
	.enqueue	=	nss_prio_enqueue,
	.dequeue	=	nss_prio_dequeue,
	.peek		=	nss_prio_peek,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
	.drop		=	nss_prio_drop,
#endif
	.init		=	nss_prio_init,
	.reset		=	nss_prio_reset,
	.destroy	=	nss_prio_destroy,
	.change		=	nss_prio_change,
	.dump		=	nss_prio_dump,
	.owner		=	THIS_MODULE,
};
