// SPDX-License-Identifier: GPL-2.0
/*
 * Tests for Generic Reed Solomon encoder / decoder library
 *
 * Written by Ferdinand Blomqvist
 * Based on previous work by Phil Karn, KA9Q
 */
#include <linux/rslib.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/slab.h>

enum verbosity {
	V_SILENT,
	V_PROGRESS,
	V_CSUMMARY
};

enum method {
	CORR_BUFFER,
	CALLER_SYNDROME,
	IN_PLACE
};

#define __param(type, name, init, msg)		\
	static type name = init;		\
	module_param(name, type, 0444);		\
	MODULE_PARM_DESC(name, msg)

__param(int, v, V_PROGRESS, "Verbosity level");
__param(int, ewsc, 1, "Erasures without symbol corruption");
__param(int, bc, 1, "Test for correct behaviour beyond error correction capacity");

struct etab {
	int	symsize;
	int	genpoly;
	int	fcs;
	int	prim;
	int	nroots;
	int	ntrials;
};

/* List of codes to test */
static struct etab Tab[] = {
	{2,	0x7,	1,	1,	1,	100000	},
	{3,	0xb,	1,	1,	2,	100000	},
	{3,	0xb,	1,	1,	3,	100000	},
	{3,	0xb,	2,	1,	4,	100000	},
	{4,	0x13,	1,	1,	4,	10000	},
	{5,	0x25,	1,	1,	6,	1000	},
	{6,	0x43,	3,	1,	8,	1000	},
	{7,	0x89,	1,	1,	14,	500	},
	{8,	0x11d,	1,	1,	30,	100	},
	{8,	0x187,	112,	11,	32,	100	},
	{9,	0x211,	1,	1,	33,	80	},
	{0, 0, 0, 0, 0, 0},
};


struct estat {
	int	dwrong;
	int	irv;
	int	wepos;
	int	nwords;
};

struct bcstat {
	int	rfail;
	int	rsuccess;
	int	noncw;
	int	nwords;
};

struct wspace {
	uint16_t	*c;		/* sent codeword */
	uint16_t	*r;		/* received word */
	uint16_t	*s;		/* syndrome */
	uint16_t	*corr;		/* correction buffer */
	int		*errlocs;
	int		*derrlocs;
};

struct pad {
	int	mult;
	int	shift;
};

static struct pad pad_coef[] = {
	{ 0, 0 },
	{ 1, 2 },
	{ 1, 1 },
	{ 3, 2 },
	{ 1, 0 },
};

static void free_ws(struct wspace *ws)
{
	if (!ws)
		return;

	kfree(ws->errlocs);
	kfree(ws->c);
	kfree(ws);
}

static struct wspace *alloc_ws(struct rs_codec *rs)
{
	int nroots = rs->nroots;
	struct wspace *ws;
	int nn = rs->nn;

	ws = kzalloc(sizeof(*ws), GFP_KERNEL);
	if (!ws)
		return NULL;

	ws->c = kmalloc_array(2 * (nn + nroots),
				sizeof(uint16_t), GFP_KERNEL);
	if (!ws->c)
		goto err;

	ws->r = ws->c + nn;
	ws->s = ws->r + nn;
	ws->corr = ws->s + nroots;

	ws->errlocs = kmalloc_array(nn + nroots, sizeof(int), GFP_KERNEL);
	if (!ws->errlocs)
		goto err;

	ws->derrlocs = ws->errlocs + nn;
	return ws;

err:
	free_ws(ws);
	return NULL;
}


/*
 * Generates a random codeword and stores it in c. Generates random errors and
 * erasures, and stores the random word with errors in r. Erasure positions are
 * stored in derrlocs, while errlocs has one of three values in every position:
 *
 * 0 if there is no error in this position;
 * 1 if there is a symbol error in this position;
 * 2 if there is an erasure without symbol corruption.
 *
 * Returns the number of corrupted symbols.
 */
static int get_rcw_we(struct rs_control *rs, struct wspace *ws,
			int len, int errs, int eras)
{
	int nroots = rs->codec->nroots;
	int *derrlocs = ws->derrlocs;
	int *errlocs = ws->errlocs;
	int dlen = len - nroots;
	int nn = rs->codec->nn;
	uint16_t *c = ws->c;
	uint16_t *r = ws->r;
	int errval;
	int errloc;
	int i;

	/* Load c with random data and encode */
	for (i = 0; i < dlen; i++)
		c[i] = prandom_u32() & nn;

	memset(c + dlen, 0, nroots * sizeof(*c));
	encode_rs16(rs, c, dlen, c + dlen, 0);

	/* Make copyand add errors and erasures */
	memcpy(r, c, len * sizeof(*r));
	memset(errlocs, 0, len * sizeof(*errlocs));
	memset(derrlocs, 0, nroots * sizeof(*derrlocs));

	/* Generating random errors */
	for (i = 0; i < errs; i++) {
		do {
			/* Error value must be nonzero */
			errval = prandom_u32() & nn;
		} while (errval == 0);

		do {
			/* Must not choose the same location twice */
			errloc = prandom_u32() % len;
		} while (errlocs[errloc] != 0);

		errlocs[errloc] = 1;
		r[errloc] ^= errval;
	}

	/* Generating random erasures */
	for (i = 0; i < eras; i++) {
		do {
			/* Must not choose the same location twice */
			errloc = prandom_u32() % len;
		} while (errlocs[errloc] != 0);

		derrlocs[i] = errloc;

		if (ewsc && (prandom_u32() & 1)) {
			/* Erasure with the symbol intact */
			errlocs[errloc] = 2;
		} else {
			/* Erasure with corrupted symbol */
			do {
				/* Error value must be nonzero */
				errval = prandom_u32() & nn;
			} while (errval == 0);

			errlocs[errloc] = 1;
			r[errloc] ^= errval;
			errs++;
		}
	}

	return errs;
}

static void fix_err(uint16_t *data, int nerrs, uint16_t *corr, int *errlocs)
{
	int i;

	for (i = 0; i < nerrs; i++)
		data[errlocs[i]] ^= corr[i];
}

static void compute_syndrome(struct rs_control *rsc, uint16_t *data,
				int len, uint16_t *syn)
{
	struct rs_codec *rs = rsc->codec;
	uint16_t *alpha_to = rs->alpha_to;
	uint16_t *index_of = rs->index_of;
	int nroots = rs->nroots;
	int prim = rs->prim;
	int fcr = rs->fcr;
	int i, j;

	/* Calculating syndrome */
	for (i = 0; i < nroots; i++) {
		syn[i] = data[0];
		for (j = 1; j < len; j++) {
			if (syn[i] == 0) {
				syn[i] = data[j];
			} else {
				syn[i] = data[j] ^
					alpha_to[rs_modnn(rs, index_of[syn[i]]
						+ (fcr + i) * prim)];
			}
		}
	}

	/* Convert to index form */
	for (i = 0; i < nroots; i++)
		syn[i] = rs->index_of[syn[i]];
}

/* Test up to error correction capacity */
static void test_uc(struct rs_control *rs, int len, int errs,
		int eras, int trials, struct estat *stat,
		struct wspace *ws, int method)
{
	int dlen = len - rs->codec->nroots;
	int *derrlocs = ws->derrlocs;
	int *errlocs = ws->errlocs;
	uint16_t *corr = ws->corr;
	uint16_t *c = ws->c;
	uint16_t *r = ws->r;
	uint16_t *s = ws->s;
	int derrs, nerrs;
	int i, j;

	for (j = 0; j < trials; j++) {
		nerrs = get_rcw_we(rs, ws, len, errs, eras);

		switch (method) {
		case CORR_BUFFER:
			derrs = decode_rs16(rs, r, r + dlen, dlen,
					NULL, eras, derrlocs, 0, corr);
			fix_err(r, derrs, corr, derrlocs);
			break;
		case CALLER_SYNDROME:
			compute_syndrome(rs, r, len, s);
			derrs = decode_rs16(rs, NULL, NULL, dlen,
					s, eras, derrlocs, 0, corr);
			fix_err(r, derrs, corr, derrlocs);
			break;
		case IN_PLACE:
			derrs = decode_rs16(rs, r, r + dlen, dlen,
					NULL, eras, derrlocs, 0, NULL);
			break;
		default:
			continue;
		}

		if (derrs != nerrs)
			stat->irv++;

		if (method != IN_PLACE) {
			for (i = 0; i < derrs; i++) {
				if (errlocs[derrlocs[i]] != 1)
					stat->wepos++;
			}
		}

		if (memcmp(r, c, len * sizeof(*r)))
			stat->dwrong++;
	}
	stat->nwords += trials;
}

static int ex_rs_helper(struct rs_control *rs, struct wspace *ws,
			int len, int trials, int method)
{
	static const char * const desc[] = {
		"Testing correction buffer interface...",
		"Testing with caller provided syndrome...",
		"Testing in-place interface..."
	};

	struct estat stat = {0, 0, 0, 0};
	int nroots = rs->codec->nroots;
	int errs, eras, retval;

	if (v >= V_PROGRESS)
		pr_info("  %s\n", desc[method]);

	for (errs = 0; errs <= nroots / 2; errs++)
		for (eras = 0; eras <= nroots - 2 * errs; eras++)
			test_uc(rs, len, errs, eras, trials, &stat, ws, method);

	if (v >= V_CSUMMARY) {
		pr_info("    Decodes wrong:        %d / %d\n",
				stat.dwrong, stat.nwords);
		pr_info("    Wrong return value:   %d / %d\n",
				stat.irv, stat.nwords);
		if (method != IN_PLACE)
			pr_info("    Wrong error position: %d\n", stat.wepos);
	}

	retval = stat.dwrong + stat.wepos + stat.irv;
	if (retval && v >= V_PROGRESS)
		pr_warn("    FAIL: %d decoding failures!\n", retval);

	return retval;
}

static int exercise_rs(struct rs_control *rs, struct wspace *ws,
		       int len, int trials)
{

	int retval = 0;
	int i;

	if (v >= V_PROGRESS)
		pr_info("Testing up to error correction capacity...\n");

	for (i = 0; i <= IN_PLACE; i++)
		retval |= ex_rs_helper(rs, ws, len, trials, i);

	return retval;
}

/* Tests for correct behaviour beyond error correction capacity */
static void test_bc(struct rs_control *rs, int len, int errs,
		int eras, int trials, struct bcstat *stat,
		struct wspace *ws)
{
	int nroots = rs->codec->nroots;
	int dlen = len - nroots;
	int *derrlocs = ws->derrlocs;
	uint16_t *corr = ws->corr;
	uint16_t *r = ws->r;
	int derrs, j;

	for (j = 0; j < trials; j++) {
		get_rcw_we(rs, ws, len, errs, eras);
		derrs = decode_rs16(rs, r, r + dlen, dlen,
				NULL, eras, derrlocs, 0, corr);
		fix_err(r, derrs, corr, derrlocs);

		if (derrs >= 0) {
			stat->rsuccess++;

			/*
			 * We check that the returned word is actually a
			 * codeword. The obvious way to do this would be to
			 * compute the syndrome, but we don't want to replicate
			 * that code here. However, all the codes are in
			 * systematic form, and therefore we can encode the
			 * returned word, and see whether the parity changes or
			 * not.
			 */
			memset(corr, 0, nroots * sizeof(*corr));
			encode_rs16(rs, r, dlen, corr, 0);

			if (memcmp(r + dlen, corr, nroots * sizeof(*corr)))
				stat->noncw++;
		} else {
			stat->rfail++;
		}
	}
	stat->nwords += trials;
}

static int exercise_rs_bc(struct rs_control *rs, struct wspace *ws,
			  int len, int trials)
{
	struct bcstat stat = {0, 0, 0, 0};
	int nroots = rs->codec->nroots;
	int errs, eras, cutoff;

	if (v >= V_PROGRESS)
		pr_info("Testing beyond error correction capacity...\n");

	for (errs = 1; errs <= nroots; errs++) {
		eras = nroots - 2 * errs + 1;
		if (eras < 0)
			eras = 0;

		cutoff = nroots <= len - errs ? nroots : len - errs;
		for (; eras <= cutoff; eras++)
			test_bc(rs, len, errs, eras, trials, &stat, ws);
	}

	if (v >= V_CSUMMARY) {
		pr_info("  decoder gives up:        %d / %d\n",
				stat.rfail, stat.nwords);
		pr_info("  decoder returns success: %d / %d\n",
				stat.rsuccess, stat.nwords);
		pr_info("    not a codeword:        %d / %d\n",
				stat.noncw, stat.rsuccess);
	}

	if (stat.noncw && v >= V_PROGRESS)
		pr_warn("    FAIL: %d silent failures!\n", stat.noncw);

	return stat.noncw;
}

static int run_exercise(struct etab *e)
{
	int nn = (1 << e->symsize) - 1;
	int kk = nn - e->nroots;
	struct rs_control *rsc;
	int retval = -ENOMEM;
	int max_pad = kk - 1;
	int prev_pad = -1;
	struct wspace *ws;
	int i;

	rsc = init_rs(e->symsize, e->genpoly, e->fcs, e->prim, e->nroots);
	if (!rsc)
		return retval;

	ws = alloc_ws(rsc->codec);
	if (!ws)
		goto err;

	retval = 0;
	for (i = 0; i < ARRAY_SIZE(pad_coef); i++) {
		int pad = (pad_coef[i].mult * max_pad) >> pad_coef[i].shift;
		int len = nn - pad;

		if (pad == prev_pad)
			continue;

		prev_pad = pad;
		if (v >= V_PROGRESS) {
			pr_info("Testing (%d,%d)_%d code...\n",
					len, kk - pad, nn + 1);
		}

		retval |= exercise_rs(rsc, ws, len, e->ntrials);
		if (bc)
			retval |= exercise_rs_bc(rsc, ws, len, e->ntrials);
	}

	free_ws(ws);

err:
	free_rs(rsc);
	return retval;
}

static int __init test_rslib_init(void)
{
	int i, fail = 0;

	for (i = 0; Tab[i].symsize != 0 ; i++) {
		int retval;

		retval = run_exercise(Tab + i);
		if (retval < 0)
			return -ENOMEM;

		fail |= retval;
	}

	if (fail)
		pr_warn("rslib: test failed\n");
	else
		pr_info("rslib: test ok\n");

	return -EAGAIN; /* Fail will directly unload the module */
}

static void __exit test_rslib_exit(void)
{
}

module_init(test_rslib_init)
module_exit(test_rslib_exit)

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ferdinand Blomqvist");
MODULE_DESCRIPTION("Reed-Solomon library test");
