// 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>
/* * 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.
*/ staticint 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] = get_random_u32() & nn;
/* 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 = get_random_u32() & nn;
} while (errval == 0);
do { /* Must not choose the same location twice */
errloc = get_random_u32_below(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 = get_random_u32_below(len);
} while (errlocs[errloc] != 0);
derrlocs[i] = errloc;
if (ewsc && get_random_u32_below(2)) { /* Erasure with the symbol intact */
errlocs[errloc] = 2;
} else { /* Erasure with corrupted symbol */ do { /* Error value must be nonzero */
errval = get_random_u32() & nn;
} while (errval == 0);
/* Convert to index form */ for (i = 0; i < nroots; i++)
syn[i] = rs->index_of[syn[i]];
}
/* Test up to error correction capacity */ staticvoid 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;
/* * 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);
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;
}
staticint 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;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.