/*
 * net/sched/sch_cbs.c	Credit Based Shaper
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Vinicius Costa Gomes <vinicius.gomes@intel.com>
 *
 */

/* Credit Based Shaper (CBS)
 * =========================
 *
 * This is a simple rate-limiting shaper aimed at TSN applications on
 * systems with known traffic workloads.
 *
 * Its algorithm is defined by the IEEE 802.1Q-2014 Specification,
 * Section 8.6.8.2, and explained in more detail in the Annex L of the
 * same specification.
 *
 * There are four tunables to be considered:
 *
 *	'idleslope': Idleslope is the rate of credits that is
 *	accumulated (in kilobits per second) when there is at least
 *	one packet waiting for transmission. Packets are transmitted
 *	when the current value of credits is equal or greater than
 *	zero. When there is no packet to be transmitted the amount of
 *	credits is set to zero. This is the main tunable of the CBS
 *	algorithm.
 *
 *	'sendslope':
 *	Sendslope is the rate of credits that is depleted (it should be a
 *	negative number of kilobits per second) when a transmission is
 *	ocurring. It can be calculated as follows, (IEEE 802.1Q-2014 Section
 *	8.6.8.2 item g):
 *
 *	sendslope = idleslope - port_transmit_rate
 *
 *	'hicredit': Hicredit defines the maximum amount of credits (in
 *	bytes) that can be accumulated. Hicredit depends on the
 *	characteristics of interfering traffic,
 *	'max_interference_size' is the maximum size of any burst of
 *	traffic that can delay the transmission of a frame that is
 *	available for transmission for this traffic class, (IEEE
 *	802.1Q-2014 Annex L, Equation L-3):
 *
 *	hicredit = max_interference_size * (idleslope / port_transmit_rate)
 *
 *	'locredit': Locredit is the minimum amount of credits that can
 *	be reached. It is a function of the traffic flowing through
 *	this qdisc (IEEE 802.1Q-2014 Annex L, Equation L-2):
 *
 *	locredit = max_frame_size * (sendslope / port_transmit_rate)
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/netevent.h>
#include <net/netlink.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>

static LIST_HEAD(cbs_list);
static DEFINE_SPINLOCK(cbs_list_lock);

#define BYTES_PER_KBIT (1000LL / 8)

struct cbs_sched_data {
	bool offload;
	int queue;
	atomic64_t port_rate; /* in bytes/s */
	s64 last; /* timestamp in ns */
	s64 credits; /* in bytes */
	s32 locredit; /* in bytes */
	s32 hicredit; /* in bytes */
	s64 sendslope; /* in bytes/s */
	s64 idleslope; /* in bytes/s */
	struct qdisc_watchdog watchdog;
	int (*enqueue)(struct sk_buff *skb, struct Qdisc *sch,
		       struct sk_buff **to_free);
	struct sk_buff *(*dequeue)(struct Qdisc *sch);
	struct Qdisc *qdisc;
	struct list_head cbs_list;
};

static int cbs_child_enqueue(struct sk_buff *skb, struct Qdisc *sch,
			     struct Qdisc *child,
			     struct sk_buff **to_free)
{
	int err;

	err = child->ops->enqueue(skb, child, to_free);
	if (err != NET_XMIT_SUCCESS)
		return err;

	qdisc_qstats_backlog_inc(sch, skb);
	sch->q.qlen++;

	return NET_XMIT_SUCCESS;
}

static int cbs_enqueue_offload(struct sk_buff *skb, struct Qdisc *sch,
			       struct sk_buff **to_free)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct Qdisc *qdisc = q->qdisc;

	return cbs_child_enqueue(skb, sch, qdisc, to_free);
}

static int cbs_enqueue_soft(struct sk_buff *skb, struct Qdisc *sch,
			    struct sk_buff **to_free)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct Qdisc *qdisc = q->qdisc;

	if (sch->q.qlen == 0 && q->credits > 0) {
		/* We need to stop accumulating credits when there's
		 * no enqueued packets and q->credits is positive.
		 */
		q->credits = 0;
		q->last = ktime_get_ns();
	}

	return cbs_child_enqueue(skb, sch, qdisc, to_free);
}

static int cbs_enqueue(struct sk_buff *skb, struct Qdisc *sch,
		       struct sk_buff **to_free)
{
	struct cbs_sched_data *q = qdisc_priv(sch);

	return q->enqueue(skb, sch, to_free);
}

/* timediff is in ns, slope is in bytes/s */
static s64 timediff_to_credits(s64 timediff, s64 slope)
{
	return div64_s64(timediff * slope, NSEC_PER_SEC);
}

static s64 delay_from_credits(s64 credits, s64 slope)
{
	if (unlikely(slope == 0))
		return S64_MAX;

	return div64_s64(-credits * NSEC_PER_SEC, slope);
}

static s64 credits_from_len(unsigned int len, s64 slope, s64 port_rate)
{
	if (unlikely(port_rate == 0))
		return S64_MAX;

	return div64_s64(len * slope, port_rate);
}

static struct sk_buff *cbs_child_dequeue(struct Qdisc *sch, struct Qdisc *child)
{
	struct sk_buff *skb;

	skb = child->ops->dequeue(child);
	if (!skb)
		return NULL;

	qdisc_qstats_backlog_dec(sch, skb);
	qdisc_bstats_update(sch, skb);
	sch->q.qlen--;

	return skb;
}

static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct Qdisc *qdisc = q->qdisc;
	s64 now = ktime_get_ns();
	struct sk_buff *skb;
	s64 credits;
	int len;

	/* The previous packet is still being sent */
	if (now < q->last) {
		qdisc_watchdog_schedule_ns(&q->watchdog, q->last);
		return NULL;
	}
	if (q->credits < 0) {
		credits = timediff_to_credits(now - q->last, q->idleslope);

		credits = q->credits + credits;
		q->credits = min_t(s64, credits, q->hicredit);

		if (q->credits < 0) {
			s64 delay;

			delay = delay_from_credits(q->credits, q->idleslope);
			qdisc_watchdog_schedule_ns(&q->watchdog, now + delay);

			q->last = now;

			return NULL;
		}
	}
	skb = cbs_child_dequeue(sch, qdisc);
	if (!skb)
		return NULL;

	len = qdisc_pkt_len(skb);

	/* As sendslope is a negative number, this will decrease the
	 * amount of q->credits.
	 */
	credits = credits_from_len(len, q->sendslope,
				   atomic64_read(&q->port_rate));
	credits += q->credits;

	q->credits = max_t(s64, credits, q->locredit);
	/* Estimate of the transmission of the last byte of the packet in ns */
	if (unlikely(atomic64_read(&q->port_rate) == 0))
		q->last = now;
	else
		q->last = now + div64_s64(len * NSEC_PER_SEC,
					  atomic64_read(&q->port_rate));

	return skb;
}

static struct sk_buff *cbs_dequeue_offload(struct Qdisc *sch)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct Qdisc *qdisc = q->qdisc;

	return cbs_child_dequeue(sch, qdisc);
}

static struct sk_buff *cbs_dequeue(struct Qdisc *sch)
{
	struct cbs_sched_data *q = qdisc_priv(sch);

	return q->dequeue(sch);
}

static const struct nla_policy cbs_policy[TCA_CBS_MAX + 1] = {
	[TCA_CBS_PARMS]	= { .len = sizeof(struct tc_cbs_qopt) },
};

static void cbs_disable_offload(struct net_device *dev,
				struct cbs_sched_data *q)
{
	struct tc_cbs_qopt_offload cbs = { };
	const struct net_device_ops *ops;
	int err;

	if (!q->offload)
		return;

	q->enqueue = cbs_enqueue_soft;
	q->dequeue = cbs_dequeue_soft;

	ops = dev->netdev_ops;
	if (!ops->ndo_setup_tc)
		return;

	cbs.queue = q->queue;
	cbs.enable = 0;

	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
	if (err < 0)
		pr_warn("Couldn't disable CBS offload for queue %d\n",
			cbs.queue);
}

static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
			      const struct tc_cbs_qopt *opt,
			      struct netlink_ext_ack *extack)
{
	const struct net_device_ops *ops = dev->netdev_ops;
	struct tc_cbs_qopt_offload cbs = { };
	int err;

	if (!ops->ndo_setup_tc) {
		NL_SET_ERR_MSG(extack, "Specified device does not support cbs offload");
		return -EOPNOTSUPP;
	}

	cbs.queue = q->queue;

	cbs.enable = 1;
	cbs.hicredit = opt->hicredit;
	cbs.locredit = opt->locredit;
	cbs.idleslope = opt->idleslope;
	cbs.sendslope = opt->sendslope;

	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
	if (err < 0) {
		NL_SET_ERR_MSG(extack, "Specified device failed to setup cbs hardware offload");
		return err;
	}

	q->enqueue = cbs_enqueue_offload;
	q->dequeue = cbs_dequeue_offload;

	return 0;
}

static void cbs_set_port_rate(struct net_device *dev, struct cbs_sched_data *q)
{
	struct ethtool_link_ksettings ecmd;
	int speed = SPEED_10;
	int port_rate = -1;
	int err;

	err = __ethtool_get_link_ksettings(dev, &ecmd);
	if (err < 0)
		goto skip;

	if (ecmd.base.speed && ecmd.base.speed != SPEED_UNKNOWN)
		speed = ecmd.base.speed;

skip:
	port_rate = speed * 1000 * BYTES_PER_KBIT;

	atomic64_set(&q->port_rate, port_rate);
	netdev_dbg(dev, "cbs: set %s's port_rate to: %lld, linkspeed: %d\n",
		   dev->name, (long long)atomic64_read(&q->port_rate),
		   ecmd.base.speed);
}

static int cbs_dev_notifier(struct notifier_block *nb, unsigned long event,
			    void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct cbs_sched_data *q;
	struct net_device *qdev;
	bool found = false;

	ASSERT_RTNL();

	if (event != NETDEV_UP && event != NETDEV_CHANGE)
		return NOTIFY_DONE;

	spin_lock(&cbs_list_lock);
	list_for_each_entry(q, &cbs_list, cbs_list) {
		qdev = qdisc_dev(q->qdisc);
		if (qdev == dev) {
			found = true;
			break;
		}
	}
	spin_unlock(&cbs_list_lock);

	if (found)
		cbs_set_port_rate(dev, q);

	return NOTIFY_DONE;
}

static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
		      struct netlink_ext_ack *extack)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct net_device *dev = qdisc_dev(sch);
	struct nlattr *tb[TCA_CBS_MAX + 1];
	struct tc_cbs_qopt *qopt;
	int err;

	err = nla_parse_nested(tb, TCA_CBS_MAX, opt, cbs_policy, extack);
	if (err < 0)
		return err;

	if (!tb[TCA_CBS_PARMS]) {
		NL_SET_ERR_MSG(extack, "Missing CBS parameter which are mandatory");
		return -EINVAL;
	}

	qopt = nla_data(tb[TCA_CBS_PARMS]);

	if (!qopt->offload) {
		cbs_set_port_rate(dev, q);
		cbs_disable_offload(dev, q);
	} else {
		err = cbs_enable_offload(dev, q, qopt, extack);
		if (err < 0)
			return err;
	}

	/* Everything went OK, save the parameters used. */
	q->hicredit = qopt->hicredit;
	q->locredit = qopt->locredit;
	q->idleslope = qopt->idleslope * BYTES_PER_KBIT;
	q->sendslope = qopt->sendslope * BYTES_PER_KBIT;
	q->offload = qopt->offload;

	return 0;
}

static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
		    struct netlink_ext_ack *extack)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct net_device *dev = qdisc_dev(sch);
	int err;

	if (!opt) {
		NL_SET_ERR_MSG(extack, "Missing CBS qdisc options  which are mandatory");
		return -EINVAL;
	}

	q->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
				     sch->handle, extack);
	if (!q->qdisc)
		return -ENOMEM;

	qdisc_hash_add(q->qdisc, false);

	q->queue = sch->dev_queue - netdev_get_tx_queue(dev, 0);

	q->enqueue = cbs_enqueue_soft;
	q->dequeue = cbs_dequeue_soft;

	qdisc_watchdog_init(&q->watchdog, sch);

	err = cbs_change(sch, opt, extack);
	if (err)
		return err;

	if (!q->offload) {
		spin_lock(&cbs_list_lock);
		list_add(&q->cbs_list, &cbs_list);
		spin_unlock(&cbs_list_lock);
	}

	return 0;
}

static void cbs_destroy(struct Qdisc *sch)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct net_device *dev = qdisc_dev(sch);

	spin_lock(&cbs_list_lock);
	list_del(&q->cbs_list);
	spin_unlock(&cbs_list_lock);

	qdisc_watchdog_cancel(&q->watchdog);
	cbs_disable_offload(dev, q);

	if (q->qdisc)
		qdisc_put(q->qdisc);
}

static int cbs_dump(struct Qdisc *sch, struct sk_buff *skb)
{
	struct cbs_sched_data *q = qdisc_priv(sch);
	struct tc_cbs_qopt opt = { };
	struct nlattr *nest;

	nest = nla_nest_start(skb, TCA_OPTIONS);
	if (!nest)
		goto nla_put_failure;

	opt.hicredit = q->hicredit;
	opt.locredit = q->locredit;
	opt.sendslope = div64_s64(q->sendslope, BYTES_PER_KBIT);
	opt.idleslope = div64_s64(q->idleslope, BYTES_PER_KBIT);
	opt.offload = q->offload;

	if (nla_put(skb, TCA_CBS_PARMS, sizeof(opt), &opt))
		goto nla_put_failure;

	return nla_nest_end(skb, nest);

nla_put_failure:
	nla_nest_cancel(skb, nest);
	return -1;
}

static int cbs_dump_class(struct Qdisc *sch, unsigned long cl,
			  struct sk_buff *skb, struct tcmsg *tcm)
{
	struct cbs_sched_data *q = qdisc_priv(sch);

	if (cl != 1 || !q->qdisc)	/* only one class */
		return -ENOENT;

	tcm->tcm_handle |= TC_H_MIN(1);
	tcm->tcm_info = q->qdisc->handle;

	return 0;
}

static int cbs_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
		     struct Qdisc **old, struct netlink_ext_ack *extack)
{
	struct cbs_sched_data *q = qdisc_priv(sch);

	if (!new) {
		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
					sch->handle, NULL);
		if (!new)
			new = &noop_qdisc;
	}

	*old = qdisc_replace(sch, new, &q->qdisc);
	return 0;
}

static struct Qdisc *cbs_leaf(struct Qdisc *sch, unsigned long arg)
{
	struct cbs_sched_data *q = qdisc_priv(sch);

	return q->qdisc;
}

static unsigned long cbs_find(struct Qdisc *sch, u32 classid)
{
	return 1;
}

static void cbs_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
	if (!walker->stop) {
		if (walker->count >= walker->skip) {
			if (walker->fn(sch, 1, walker) < 0) {
				walker->stop = 1;
				return;
			}
		}
		walker->count++;
	}
}

static const struct Qdisc_class_ops cbs_class_ops = {
	.graft		=	cbs_graft,
	.leaf		=	cbs_leaf,
	.find		=	cbs_find,
	.walk		=	cbs_walk,
	.dump		=	cbs_dump_class,
};

static struct Qdisc_ops cbs_qdisc_ops __read_mostly = {
	.id		=	"cbs",
	.cl_ops		=	&cbs_class_ops,
	.priv_size	=	sizeof(struct cbs_sched_data),
	.enqueue	=	cbs_enqueue,
	.dequeue	=	cbs_dequeue,
	.peek		=	qdisc_peek_dequeued,
	.init		=	cbs_init,
	.reset		=	qdisc_reset_queue,
	.destroy	=	cbs_destroy,
	.change		=	cbs_change,
	.dump		=	cbs_dump,
	.owner		=	THIS_MODULE,
};

static struct notifier_block cbs_device_notifier = {
	.notifier_call = cbs_dev_notifier,
};

static int __init cbs_module_init(void)
{
	int err;

	err = register_netdevice_notifier(&cbs_device_notifier);
	if (err)
		return err;

	err = register_qdisc(&cbs_qdisc_ops);
	if (err)
		unregister_netdevice_notifier(&cbs_device_notifier);

	return err;
}

static void __exit cbs_module_exit(void)
{
	unregister_qdisc(&cbs_qdisc_ops);
	unregister_netdevice_notifier(&cbs_device_notifier);
}
module_init(cbs_module_init)
module_exit(cbs_module_exit)
MODULE_LICENSE("GPL");
