1 /* 2 * Generic Reed Solomon encoder / decoder library 3 * 4 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 5 * 6 * Reed Solomon code lifted from reed solomon library written by Phil Karn 7 * Copyright 2002 Phil Karn, KA9Q 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * Description: 14 * 15 * The generic Reed Solomon library provides runtime configurable 16 * encoding / decoding of RS codes. 17 * Each user must call init_rs to get a pointer to a rs_control 18 * structure for the given rs parameters. This structure is either 19 * generated or a already available matching control structure is used. 20 * If a structure is generated then the polynomial arrays for 21 * fast encoding / decoding are built. This can take some time so 22 * make sure not to call this function from a time critical path. 23 * Usually a module / driver should initialize the necessary 24 * rs_control structure on module / driver init and release it 25 * on exit. 26 * The encoding puts the calculated syndrome into a given syndrome 27 * buffer. 28 * The decoding is a two step process. The first step calculates 29 * the syndrome over the received (data + syndrome) and calls the 30 * second stage, which does the decoding / error correction itself. 31 * Many hw encoders provide a syndrome calculation over the received 32 * data + syndrome and can call the second stage directly. 33 */ 34 #include <linux/errno.h> 35 #include <linux/kernel.h> 36 #include <linux/init.h> 37 #include <linux/module.h> 38 #include <linux/rslib.h> 39 #include <linux/slab.h> 40 #include <linux/mutex.h> 41 42 /* This list holds all currently allocated rs control structures */ 43 static LIST_HEAD (rslist); 44 /* Protection for the list */ 45 static DEFINE_MUTEX(rslistlock); 46 47 /** 48 * rs_init - Initialize a Reed-Solomon codec 49 * @symsize: symbol size, bits (1-8) 50 * @gfpoly: Field generator polynomial coefficients 51 * @gffunc: Field generator function 52 * @fcr: first root of RS code generator polynomial, index form 53 * @prim: primitive element to generate polynomial roots 54 * @nroots: RS code generator polynomial degree (number of roots) 55 * @gfp: GFP_ flags for allocations 56 * 57 * Allocate a control structure and the polynom arrays for faster 58 * en/decoding. Fill the arrays according to the given parameters. 59 */ 60 static struct rs_control *rs_init(int symsize, int gfpoly, int (*gffunc)(int), 61 int fcr, int prim, int nroots, gfp_t gfp) 62 { 63 struct rs_control *rs; 64 int i, j, sr, root, iprim; 65 66 /* Allocate the control structure */ 67 rs = kmalloc(sizeof(*rs), gfp); 68 if (!rs) 69 return NULL; 70 71 INIT_LIST_HEAD(&rs->list); 72 73 rs->mm = symsize; 74 rs->nn = (1 << symsize) - 1; 75 rs->fcr = fcr; 76 rs->prim = prim; 77 rs->nroots = nroots; 78 rs->gfpoly = gfpoly; 79 rs->gffunc = gffunc; 80 81 /* Allocate the arrays */ 82 rs->alpha_to = kmalloc(sizeof(uint16_t) * (rs->nn + 1), gfp); 83 if (rs->alpha_to == NULL) 84 goto errrs; 85 86 rs->index_of = kmalloc(sizeof(uint16_t) * (rs->nn + 1), gfp); 87 if (rs->index_of == NULL) 88 goto erralp; 89 90 rs->genpoly = kmalloc(sizeof(uint16_t) * (rs->nroots + 1), gfp); 91 if(rs->genpoly == NULL) 92 goto erridx; 93 94 /* Generate Galois field lookup tables */ 95 rs->index_of[0] = rs->nn; /* log(zero) = -inf */ 96 rs->alpha_to[rs->nn] = 0; /* alpha**-inf = 0 */ 97 if (gfpoly) { 98 sr = 1; 99 for (i = 0; i < rs->nn; i++) { 100 rs->index_of[sr] = i; 101 rs->alpha_to[i] = sr; 102 sr <<= 1; 103 if (sr & (1 << symsize)) 104 sr ^= gfpoly; 105 sr &= rs->nn; 106 } 107 } else { 108 sr = gffunc(0); 109 for (i = 0; i < rs->nn; i++) { 110 rs->index_of[sr] = i; 111 rs->alpha_to[i] = sr; 112 sr = gffunc(sr); 113 } 114 } 115 /* If it's not primitive, exit */ 116 if(sr != rs->alpha_to[0]) 117 goto errpol; 118 119 /* Find prim-th root of 1, used in decoding */ 120 for(iprim = 1; (iprim % prim) != 0; iprim += rs->nn); 121 /* prim-th root of 1, index form */ 122 rs->iprim = iprim / prim; 123 124 /* Form RS code generator polynomial from its roots */ 125 rs->genpoly[0] = 1; 126 for (i = 0, root = fcr * prim; i < nroots; i++, root += prim) { 127 rs->genpoly[i + 1] = 1; 128 /* Multiply rs->genpoly[] by @**(root + x) */ 129 for (j = i; j > 0; j--) { 130 if (rs->genpoly[j] != 0) { 131 rs->genpoly[j] = rs->genpoly[j -1] ^ 132 rs->alpha_to[rs_modnn(rs, 133 rs->index_of[rs->genpoly[j]] + root)]; 134 } else 135 rs->genpoly[j] = rs->genpoly[j - 1]; 136 } 137 /* rs->genpoly[0] can never be zero */ 138 rs->genpoly[0] = 139 rs->alpha_to[rs_modnn(rs, 140 rs->index_of[rs->genpoly[0]] + root)]; 141 } 142 /* convert rs->genpoly[] to index form for quicker encoding */ 143 for (i = 0; i <= nroots; i++) 144 rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; 145 return rs; 146 147 /* Error exit */ 148 errpol: 149 kfree(rs->genpoly); 150 erridx: 151 kfree(rs->index_of); 152 erralp: 153 kfree(rs->alpha_to); 154 errrs: 155 kfree(rs); 156 return NULL; 157 } 158 159 160 /** 161 * free_rs - Free the rs control structure, if it is no longer used 162 * @rs: the control structure which is not longer used by the 163 * caller 164 */ 165 void free_rs(struct rs_control *rs) 166 { 167 mutex_lock(&rslistlock); 168 rs->users--; 169 if(!rs->users) { 170 list_del(&rs->list); 171 kfree(rs->alpha_to); 172 kfree(rs->index_of); 173 kfree(rs->genpoly); 174 kfree(rs); 175 } 176 mutex_unlock(&rslistlock); 177 } 178 EXPORT_SYMBOL_GPL(free_rs); 179 180 /** 181 * init_rs_internal - Find a matching or allocate a new rs control structure 182 * @symsize: the symbol size (number of bits) 183 * @gfpoly: the extended Galois field generator polynomial coefficients, 184 * with the 0th coefficient in the low order bit. The polynomial 185 * must be primitive; 186 * @gffunc: pointer to function to generate the next field element, 187 * or the multiplicative identity element if given 0. Used 188 * instead of gfpoly if gfpoly is 0 189 * @fcr: the first consecutive root of the rs code generator polynomial 190 * in index form 191 * @prim: primitive element to generate polynomial roots 192 * @nroots: RS code generator polynomial degree (number of roots) 193 * @gfp: GFP_ flags for allocations 194 */ 195 static struct rs_control *init_rs_internal(int symsize, int gfpoly, 196 int (*gffunc)(int), int fcr, 197 int prim, int nroots, gfp_t gfp) 198 { 199 struct list_head *tmp; 200 struct rs_control *rs; 201 202 /* Sanity checks */ 203 if (symsize < 1) 204 return NULL; 205 if (fcr < 0 || fcr >= (1<<symsize)) 206 return NULL; 207 if (prim <= 0 || prim >= (1<<symsize)) 208 return NULL; 209 if (nroots < 0 || nroots >= (1<<symsize)) 210 return NULL; 211 212 mutex_lock(&rslistlock); 213 214 /* Walk through the list and look for a matching entry */ 215 list_for_each(tmp, &rslist) { 216 rs = list_entry(tmp, struct rs_control, list); 217 if (symsize != rs->mm) 218 continue; 219 if (gfpoly != rs->gfpoly) 220 continue; 221 if (gffunc != rs->gffunc) 222 continue; 223 if (fcr != rs->fcr) 224 continue; 225 if (prim != rs->prim) 226 continue; 227 if (nroots != rs->nroots) 228 continue; 229 /* We have a matching one already */ 230 rs->users++; 231 goto out; 232 } 233 234 /* Create a new one */ 235 rs = rs_init(symsize, gfpoly, gffunc, fcr, prim, nroots, gfp); 236 if (rs) { 237 rs->users = 1; 238 list_add(&rs->list, &rslist); 239 } 240 out: 241 mutex_unlock(&rslistlock); 242 return rs; 243 } 244 245 /** 246 * init_rs_gfp - Find a matching or allocate a new rs control structure 247 * @symsize: the symbol size (number of bits) 248 * @gfpoly: the extended Galois field generator polynomial coefficients, 249 * with the 0th coefficient in the low order bit. The polynomial 250 * must be primitive; 251 * @fcr: the first consecutive root of the rs code generator polynomial 252 * in index form 253 * @prim: primitive element to generate polynomial roots 254 * @nroots: RS code generator polynomial degree (number of roots) 255 * @gfp: GFP_ flags for allocations 256 */ 257 struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim, 258 int nroots, gfp_t gfp) 259 { 260 return init_rs_internal(symsize, gfpoly, NULL, fcr, prim, nroots, gfp); 261 } 262 EXPORT_SYMBOL_GPL(init_rs_gfp); 263 264 /** 265 * init_rs_non_canonical - Find a matching or allocate a new rs control 266 * structure, for fields with non-canonical 267 * representation 268 * @symsize: the symbol size (number of bits) 269 * @gffunc: pointer to function to generate the next field element, 270 * or the multiplicative identity element if given 0. Used 271 * instead of gfpoly if gfpoly is 0 272 * @fcr: the first consecutive root of the rs code generator polynomial 273 * in index form 274 * @prim: primitive element to generate polynomial roots 275 * @nroots: RS code generator polynomial degree (number of roots) 276 */ 277 struct rs_control *init_rs_non_canonical(int symsize, int (*gffunc)(int), 278 int fcr, int prim, int nroots) 279 { 280 return init_rs_internal(symsize, 0, gffunc, fcr, prim, nroots, 281 GFP_KERNEL); 282 } 283 EXPORT_SYMBOL_GPL(init_rs_non_canonical); 284 285 #ifdef CONFIG_REED_SOLOMON_ENC8 286 /** 287 * encode_rs8 - Calculate the parity for data values (8bit data width) 288 * @rs: the rs control structure 289 * @data: data field of a given type 290 * @len: data length 291 * @par: parity data, must be initialized by caller (usually all 0) 292 * @invmsk: invert data mask (will be xored on data) 293 * 294 * The parity uses a uint16_t data type to enable 295 * symbol size > 8. The calling code must take care of encoding of the 296 * syndrome result for storage itself. 297 */ 298 int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par, 299 uint16_t invmsk) 300 { 301 #include "encode_rs.c" 302 } 303 EXPORT_SYMBOL_GPL(encode_rs8); 304 #endif 305 306 #ifdef CONFIG_REED_SOLOMON_DEC8 307 /** 308 * decode_rs8 - Decode codeword (8bit data width) 309 * @rs: the rs control structure 310 * @data: data field of a given type 311 * @par: received parity data field 312 * @len: data length 313 * @s: syndrome data field (if NULL, syndrome is calculated) 314 * @no_eras: number of erasures 315 * @eras_pos: position of erasures, can be NULL 316 * @invmsk: invert data mask (will be xored on data, not on parity!) 317 * @corr: buffer to store correction bitmask on eras_pos 318 * 319 * The syndrome and parity uses a uint16_t data type to enable 320 * symbol size > 8. The calling code must take care of decoding of the 321 * syndrome result and the received parity before calling this code. 322 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors. 323 */ 324 int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len, 325 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, 326 uint16_t *corr) 327 { 328 #include "decode_rs.c" 329 } 330 EXPORT_SYMBOL_GPL(decode_rs8); 331 #endif 332 333 #ifdef CONFIG_REED_SOLOMON_ENC16 334 /** 335 * encode_rs16 - Calculate the parity for data values (16bit data width) 336 * @rs: the rs control structure 337 * @data: data field of a given type 338 * @len: data length 339 * @par: parity data, must be initialized by caller (usually all 0) 340 * @invmsk: invert data mask (will be xored on data, not on parity!) 341 * 342 * Each field in the data array contains up to symbol size bits of valid data. 343 */ 344 int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par, 345 uint16_t invmsk) 346 { 347 #include "encode_rs.c" 348 } 349 EXPORT_SYMBOL_GPL(encode_rs16); 350 #endif 351 352 #ifdef CONFIG_REED_SOLOMON_DEC16 353 /** 354 * decode_rs16 - Decode codeword (16bit data width) 355 * @rs: the rs control structure 356 * @data: data field of a given type 357 * @par: received parity data field 358 * @len: data length 359 * @s: syndrome data field (if NULL, syndrome is calculated) 360 * @no_eras: number of erasures 361 * @eras_pos: position of erasures, can be NULL 362 * @invmsk: invert data mask (will be xored on data, not on parity!) 363 * @corr: buffer to store correction bitmask on eras_pos 364 * 365 * Each field in the data array contains up to symbol size bits of valid data. 366 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors. 367 */ 368 int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len, 369 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, 370 uint16_t *corr) 371 { 372 #include "decode_rs.c" 373 } 374 EXPORT_SYMBOL_GPL(decode_rs16); 375 #endif 376 377 MODULE_LICENSE("GPL"); 378 MODULE_DESCRIPTION("Reed Solomon encoder/decoder"); 379 MODULE_AUTHOR("Phil Karn, Thomas Gleixner"); 380 381