/* SCTP kernel implementation
 * (C) Copyright Red Hat Inc. 2017
 *
 * This file is part of the SCTP kernel implementation
 *
 * These functions manipulate sctp stream queue/scheduling.
 *
 * This SCTP implementation 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, or (at your option)
 * any later version.
 *
 * This SCTP implementation is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *                 ************************
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU CC; see the file COPYING.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Please send any bug reports or fixes you make to the
 * email addresched(es):
 *    lksctp developers <linux-sctp@vger.kernel.org>
 *
 * Written or modified by:
 *    Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
 */

#include <linux/list.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
#include <net/sctp/stream_sched.h>

/* First Come First Serve (a.k.a. FIFO)
 * RFC DRAFT ndata Section 3.1
 */
static int sctp_sched_fcfs_set(struct sctp_stream *stream, __u16 sid,
			       __u16 value, gfp_t gfp)
{
	return 0;
}

static int sctp_sched_fcfs_get(struct sctp_stream *stream, __u16 sid,
			       __u16 *value)
{
	*value = 0;
	return 0;
}

static int sctp_sched_fcfs_init(struct sctp_stream *stream)
{
	return 0;
}

static int sctp_sched_fcfs_init_sid(struct sctp_stream *stream, __u16 sid,
				    gfp_t gfp)
{
	return 0;
}

static void sctp_sched_fcfs_free(struct sctp_stream *stream)
{
}

static void sctp_sched_fcfs_enqueue(struct sctp_outq *q,
				    struct sctp_datamsg *msg)
{
}

static struct sctp_chunk *sctp_sched_fcfs_dequeue(struct sctp_outq *q)
{
	struct sctp_stream *stream = &q->asoc->stream;
	struct sctp_chunk *ch = NULL;
	struct list_head *entry;

	if (list_empty(&q->out_chunk_list))
		goto out;

	if (stream->out_curr) {
		ch = list_entry(stream->out_curr->ext->outq.next,
				struct sctp_chunk, stream_list);
	} else {
		entry = q->out_chunk_list.next;
		ch = list_entry(entry, struct sctp_chunk, list);
	}

	sctp_sched_dequeue_common(q, ch);

out:
	return ch;
}

static void sctp_sched_fcfs_dequeue_done(struct sctp_outq *q,
					 struct sctp_chunk *chunk)
{
}

static void sctp_sched_fcfs_sched_all(struct sctp_stream *stream)
{
}

static void sctp_sched_fcfs_unsched_all(struct sctp_stream *stream)
{
}

static struct sctp_sched_ops sctp_sched_fcfs = {
	.set = sctp_sched_fcfs_set,
	.get = sctp_sched_fcfs_get,
	.init = sctp_sched_fcfs_init,
	.init_sid = sctp_sched_fcfs_init_sid,
	.free = sctp_sched_fcfs_free,
	.enqueue = sctp_sched_fcfs_enqueue,
	.dequeue = sctp_sched_fcfs_dequeue,
	.dequeue_done = sctp_sched_fcfs_dequeue_done,
	.sched_all = sctp_sched_fcfs_sched_all,
	.unsched_all = sctp_sched_fcfs_unsched_all,
};

/* API to other parts of the stack */

extern struct sctp_sched_ops sctp_sched_prio;
extern struct sctp_sched_ops sctp_sched_rr;

static struct sctp_sched_ops *sctp_sched_ops[] = {
	&sctp_sched_fcfs,
	&sctp_sched_prio,
	&sctp_sched_rr,
};

int sctp_sched_set_sched(struct sctp_association *asoc,
			 enum sctp_sched_type sched)
{
	struct sctp_sched_ops *n = sctp_sched_ops[sched];
	struct sctp_sched_ops *old = asoc->outqueue.sched;
	struct sctp_datamsg *msg = NULL;
	struct sctp_chunk *ch;
	int i, ret = 0;

	if (old == n)
		return ret;

	if (sched > SCTP_SS_MAX)
		return -EINVAL;

	if (old) {
		old->free(&asoc->stream);

		/* Give the next scheduler a clean slate. */
		for (i = 0; i < asoc->stream.outcnt; i++) {
			void *p = asoc->stream.out[i].ext;

			if (!p)
				continue;

			p += offsetofend(struct sctp_stream_out_ext, outq);
			memset(p, 0, sizeof(struct sctp_stream_out_ext) -
				     offsetofend(struct sctp_stream_out_ext, outq));
		}
	}

	asoc->outqueue.sched = n;
	n->init(&asoc->stream);
	for (i = 0; i < asoc->stream.outcnt; i++) {
		if (!asoc->stream.out[i].ext)
			continue;

		ret = n->init_sid(&asoc->stream, i, GFP_KERNEL);
		if (ret)
			goto err;
	}

	/* We have to requeue all chunks already queued. */
	list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list) {
		if (ch->msg == msg)
			continue;
		msg = ch->msg;
		n->enqueue(&asoc->outqueue, msg);
	}

	return ret;

err:
	n->free(&asoc->stream);
	asoc->outqueue.sched = &sctp_sched_fcfs; /* Always safe */

	return ret;
}

int sctp_sched_get_sched(struct sctp_association *asoc)
{
	int i;

	for (i = 0; i <= SCTP_SS_MAX; i++)
		if (asoc->outqueue.sched == sctp_sched_ops[i])
			return i;

	return 0;
}

int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid,
			 __u16 value, gfp_t gfp)
{
	if (sid >= asoc->stream.outcnt)
		return -EINVAL;

	if (!asoc->stream.out[sid].ext) {
		int ret;

		ret = sctp_stream_init_ext(&asoc->stream, sid);
		if (ret)
			return ret;
	}

	return asoc->outqueue.sched->set(&asoc->stream, sid, value, gfp);
}

int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid,
			 __u16 *value)
{
	if (sid >= asoc->stream.outcnt)
		return -EINVAL;

	if (!asoc->stream.out[sid].ext)
		return 0;

	return asoc->outqueue.sched->get(&asoc->stream, sid, value);
}

void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch)
{
	if (!list_is_last(&ch->frag_list, &ch->msg->chunks)) {
		struct sctp_stream_out *sout;
		__u16 sid;

		/* datamsg is not finish, so save it as current one,
		 * in case application switch scheduler or a higher
		 * priority stream comes in.
		 */
		sid = sctp_chunk_stream_no(ch);
		sout = &q->asoc->stream.out[sid];
		q->asoc->stream.out_curr = sout;
		return;
	}

	q->asoc->stream.out_curr = NULL;
	q->sched->dequeue_done(q, ch);
}

/* Auxiliary functions for the schedulers */
void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch)
{
	list_del_init(&ch->list);
	list_del_init(&ch->stream_list);
	q->out_qlen -= ch->skb->len;
}

int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp)
{
	struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);

	INIT_LIST_HEAD(&stream->out[sid].ext->outq);
	return sched->init_sid(stream, sid, gfp);
}

struct sctp_sched_ops *sctp_sched_ops_from_stream(struct sctp_stream *stream)
{
	struct sctp_association *asoc;

	asoc = container_of(stream, struct sctp_association, stream);

	return asoc->outqueue.sched;
}
