^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Tests for Generic Reed Solomon encoder / decoder library
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by Ferdinand Blomqvist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based on previous work by Phil Karn, KA9Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/rslib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) enum verbosity {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) V_SILENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) V_PROGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) V_CSUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) enum method {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) CORR_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) CALLER_SYNDROME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) IN_PLACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define __param(type, name, init, msg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static type name = init; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) module_param(name, type, 0444); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_PARM_DESC(name, msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __param(int, v, V_PROGRESS, "Verbosity level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __param(int, ewsc, 1, "Erasures without symbol corruption");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) __param(int, bc, 1, "Test for correct behaviour beyond error correction capacity");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct etab {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int symsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int genpoly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int fcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int prim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int ntrials;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* List of codes to test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static struct etab Tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {2, 0x7, 1, 1, 1, 100000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {3, 0xb, 1, 1, 2, 100000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {3, 0xb, 1, 1, 3, 100000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {3, 0xb, 2, 1, 4, 100000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {4, 0x13, 1, 1, 4, 10000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {5, 0x25, 1, 1, 6, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {6, 0x43, 3, 1, 8, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {7, 0x89, 1, 1, 14, 500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {8, 0x11d, 1, 1, 30, 100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {8, 0x187, 112, 11, 32, 100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {9, 0x211, 1, 1, 33, 80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {0, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct estat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int dwrong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int irv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int wepos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int nwords;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct bcstat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int rfail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int rsuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int noncw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int nwords;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct wspace {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) uint16_t *c; /* sent codeword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) uint16_t *r; /* received word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) uint16_t *s; /* syndrome */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) uint16_t *corr; /* correction buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int *errlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int *derrlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct pad {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static struct pad pad_coef[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) { 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) { 1, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) { 1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { 3, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void free_ws(struct wspace *ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (!ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) kfree(ws->errlocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) kfree(ws->c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kfree(ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct wspace *alloc_ws(struct rs_codec *rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int nroots = rs->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct wspace *ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int nn = rs->nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ws = kzalloc(sizeof(*ws), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ws->c = kmalloc_array(2 * (nn + nroots),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) sizeof(uint16_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!ws->c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ws->r = ws->c + nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ws->s = ws->r + nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ws->corr = ws->s + nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ws->errlocs = kmalloc_array(nn + nroots, sizeof(int), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!ws->errlocs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ws->derrlocs = ws->errlocs + nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) free_ws(ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Generates a random codeword and stores it in c. Generates random errors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * erasures, and stores the random word with errors in r. Erasure positions are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * stored in derrlocs, while errlocs has one of three values in every position:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * 0 if there is no error in this position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * 1 if there is a symbol error in this position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * 2 if there is an erasure without symbol corruption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Returns the number of corrupted symbols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int get_rcw_we(struct rs_control *rs, struct wspace *ws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int len, int errs, int eras)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int nroots = rs->codec->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int *derrlocs = ws->derrlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int *errlocs = ws->errlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int dlen = len - nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int nn = rs->codec->nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) uint16_t *c = ws->c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) uint16_t *r = ws->r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int errval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int errloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Load c with random data and encode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (i = 0; i < dlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) c[i] = prandom_u32() & nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) memset(c + dlen, 0, nroots * sizeof(*c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) encode_rs16(rs, c, dlen, c + dlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Make copyand add errors and erasures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) memcpy(r, c, len * sizeof(*r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) memset(errlocs, 0, len * sizeof(*errlocs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) memset(derrlocs, 0, nroots * sizeof(*derrlocs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Generating random errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) for (i = 0; i < errs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Error value must be nonzero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) errval = prandom_u32() & nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) } while (errval == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Must not choose the same location twice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) errloc = prandom_u32() % len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } while (errlocs[errloc] != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) errlocs[errloc] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) r[errloc] ^= errval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Generating random erasures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for (i = 0; i < eras; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Must not choose the same location twice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) errloc = prandom_u32() % len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } while (errlocs[errloc] != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) derrlocs[i] = errloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ewsc && (prandom_u32() & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Erasure with the symbol intact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) errlocs[errloc] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Erasure with corrupted symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Error value must be nonzero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) errval = prandom_u32() & nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) } while (errval == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) errlocs[errloc] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) r[errloc] ^= errval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) errs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return errs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void fix_err(uint16_t *data, int nerrs, uint16_t *corr, int *errlocs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) for (i = 0; i < nerrs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) data[errlocs[i]] ^= corr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void compute_syndrome(struct rs_control *rsc, uint16_t *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int len, uint16_t *syn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct rs_codec *rs = rsc->codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) uint16_t *alpha_to = rs->alpha_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) uint16_t *index_of = rs->index_of;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int nroots = rs->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int prim = rs->prim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int fcr = rs->fcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Calculating syndrome */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) for (i = 0; i < nroots; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) syn[i] = data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) for (j = 1; j < len; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (syn[i] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) syn[i] = data[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) syn[i] = data[j] ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) alpha_to[rs_modnn(rs, index_of[syn[i]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) + (fcr + i) * prim)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* Convert to index form */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) for (i = 0; i < nroots; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) syn[i] = rs->index_of[syn[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* Test up to error correction capacity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void test_uc(struct rs_control *rs, int len, int errs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int eras, int trials, struct estat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct wspace *ws, int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int dlen = len - rs->codec->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int *derrlocs = ws->derrlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int *errlocs = ws->errlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) uint16_t *corr = ws->corr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) uint16_t *c = ws->c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) uint16_t *r = ws->r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) uint16_t *s = ws->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int derrs, nerrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) for (j = 0; j < trials; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) nerrs = get_rcw_we(rs, ws, len, errs, eras);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (method) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case CORR_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) derrs = decode_rs16(rs, r, r + dlen, dlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) NULL, eras, derrlocs, 0, corr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) fix_err(r, derrs, corr, derrlocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case CALLER_SYNDROME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) compute_syndrome(rs, r, len, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) derrs = decode_rs16(rs, NULL, NULL, dlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) s, eras, derrlocs, 0, corr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) fix_err(r, derrs, corr, derrlocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case IN_PLACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) derrs = decode_rs16(rs, r, r + dlen, dlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) NULL, eras, derrlocs, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (derrs != nerrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) stat->irv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (method != IN_PLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for (i = 0; i < derrs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (errlocs[derrlocs[i]] != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) stat->wepos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (memcmp(r, c, len * sizeof(*r)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) stat->dwrong++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) stat->nwords += trials;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int ex_rs_helper(struct rs_control *rs, struct wspace *ws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int len, int trials, int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static const char * const desc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) "Testing correction buffer interface...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) "Testing with caller provided syndrome...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) "Testing in-place interface..."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct estat stat = {0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int nroots = rs->codec->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int errs, eras, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (v >= V_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) pr_info(" %s\n", desc[method]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) for (errs = 0; errs <= nroots / 2; errs++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) for (eras = 0; eras <= nroots - 2 * errs; eras++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) test_uc(rs, len, errs, eras, trials, &stat, ws, method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (v >= V_CSUMMARY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) pr_info(" Decodes wrong: %d / %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) stat.dwrong, stat.nwords);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pr_info(" Wrong return value: %d / %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) stat.irv, stat.nwords);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (method != IN_PLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) pr_info(" Wrong error position: %d\n", stat.wepos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) retval = stat.dwrong + stat.wepos + stat.irv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (retval && v >= V_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pr_warn(" FAIL: %d decoding failures!\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int exercise_rs(struct rs_control *rs, struct wspace *ws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int len, int trials)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (v >= V_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pr_info("Testing up to error correction capacity...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) for (i = 0; i <= IN_PLACE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) retval |= ex_rs_helper(rs, ws, len, trials, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Tests for correct behaviour beyond error correction capacity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void test_bc(struct rs_control *rs, int len, int errs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int eras, int trials, struct bcstat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct wspace *ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int nroots = rs->codec->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int dlen = len - nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int *derrlocs = ws->derrlocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) uint16_t *corr = ws->corr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) uint16_t *r = ws->r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int derrs, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (j = 0; j < trials; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) get_rcw_we(rs, ws, len, errs, eras);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) derrs = decode_rs16(rs, r, r + dlen, dlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) NULL, eras, derrlocs, 0, corr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fix_err(r, derrs, corr, derrlocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (derrs >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) stat->rsuccess++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * We check that the returned word is actually a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * codeword. The obious way to do this would be to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * compute the syndrome, but we don't want to replicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * that code here. However, all the codes are in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * systematic form, and therefore we can encode the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * returned word, and see whether the parity changes or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) memset(corr, 0, nroots * sizeof(*corr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) encode_rs16(rs, r, dlen, corr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (memcmp(r + dlen, corr, nroots * sizeof(*corr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) stat->noncw++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) stat->rfail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) stat->nwords += trials;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static int exercise_rs_bc(struct rs_control *rs, struct wspace *ws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int len, int trials)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct bcstat stat = {0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int nroots = rs->codec->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int errs, eras, cutoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (v >= V_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pr_info("Testing beyond error correction capacity...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) for (errs = 1; errs <= nroots; errs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) eras = nroots - 2 * errs + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (eras < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) eras = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) cutoff = nroots <= len - errs ? nroots : len - errs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (; eras <= cutoff; eras++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) test_bc(rs, len, errs, eras, trials, &stat, ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (v >= V_CSUMMARY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) pr_info(" decoder gives up: %d / %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) stat.rfail, stat.nwords);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pr_info(" decoder returns success: %d / %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) stat.rsuccess, stat.nwords);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pr_info(" not a codeword: %d / %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) stat.noncw, stat.rsuccess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (stat.noncw && v >= V_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pr_warn(" FAIL: %d silent failures!\n", stat.noncw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return stat.noncw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int run_exercise(struct etab *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int nn = (1 << e->symsize) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int kk = nn - e->nroots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct rs_control *rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int max_pad = kk - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int prev_pad = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct wspace *ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rsc = init_rs(e->symsize, e->genpoly, e->fcs, e->prim, e->nroots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ws = alloc_ws(rsc->codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) for (i = 0; i < ARRAY_SIZE(pad_coef); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int pad = (pad_coef[i].mult * max_pad) >> pad_coef[i].shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int len = nn - pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (pad == prev_pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) prev_pad = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (v >= V_PROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) pr_info("Testing (%d,%d)_%d code...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) len, kk - pad, nn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) retval |= exercise_rs(rsc, ws, len, e->ntrials);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) retval |= exercise_rs_bc(rsc, ws, len, e->ntrials);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) free_ws(ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) free_rs(rsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int __init test_rslib_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int i, fail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) for (i = 0; Tab[i].symsize != 0 ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) retval = run_exercise(Tab + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) fail |= retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (fail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pr_warn("rslib: test failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pr_info("rslib: test ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EAGAIN; /* Fail will directly unload the module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void __exit test_rslib_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) module_init(test_rslib_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) module_exit(test_rslib_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) MODULE_AUTHOR("Ferdinand Blomqvist");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) MODULE_DESCRIPTION("Reed-Solomon library test");