Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Generic Reed Solomon encoder / decoder library
0004  *
0005  * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
0006  *
0007  * RS code lifted from reed solomon library written by Phil Karn
0008  * Copyright 2002 Phil Karn, KA9Q
0009  */
0010 #ifndef _RSLIB_H_
0011 #define _RSLIB_H_
0012 
0013 #include <linux/list.h>
0014 #include <linux/types.h>    /* for gfp_t */
0015 #include <linux/gfp.h>      /* for GFP_KERNEL */
0016 
0017 /**
0018  * struct rs_codec - rs codec data
0019  *
0020  * @mm:     Bits per symbol
0021  * @nn:     Symbols per block (= (1<<mm)-1)
0022  * @alpha_to:   log lookup table
0023  * @index_of:   Antilog lookup table
0024  * @genpoly:    Generator polynomial
0025  * @nroots: Number of generator roots = number of parity symbols
0026  * @fcr:    First consecutive root, index form
0027  * @prim:   Primitive element, index form
0028  * @iprim:  prim-th root of 1, index form
0029  * @gfpoly: The primitive generator polynominal
0030  * @gffunc: Function to generate the field, if non-canonical representation
0031  * @users:  Users of this structure
0032  * @list:   List entry for the rs codec list
0033 */
0034 struct rs_codec {
0035     int     mm;
0036     int     nn;
0037     uint16_t    *alpha_to;
0038     uint16_t    *index_of;
0039     uint16_t    *genpoly;
0040     int     nroots;
0041     int     fcr;
0042     int     prim;
0043     int     iprim;
0044     int     gfpoly;
0045     int     (*gffunc)(int);
0046     int     users;
0047     struct list_head list;
0048 };
0049 
0050 /**
0051  * struct rs_control - rs control structure per instance
0052  * @codec:  The codec used for this instance
0053  * @buffers:    Internal scratch buffers used in calls to decode_rs()
0054  */
0055 struct rs_control {
0056     struct rs_codec *codec;
0057     uint16_t    buffers[];
0058 };
0059 
0060 /* General purpose RS codec, 8-bit data width, symbol width 1-15 bit  */
0061 #ifdef CONFIG_REED_SOLOMON_ENC8
0062 int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
0063            uint16_t invmsk);
0064 #endif
0065 #ifdef CONFIG_REED_SOLOMON_DEC8
0066 int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
0067         uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
0068            uint16_t *corr);
0069 #endif
0070 
0071 /* General purpose RS codec, 16-bit data width, symbol width 1-15 bit  */
0072 #ifdef CONFIG_REED_SOLOMON_ENC16
0073 int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par,
0074         uint16_t invmsk);
0075 #endif
0076 #ifdef CONFIG_REED_SOLOMON_DEC16
0077 int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
0078         uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
0079         uint16_t *corr);
0080 #endif
0081 
0082 struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim,
0083                    int nroots, gfp_t gfp);
0084 
0085 /**
0086  * init_rs - Create a RS control struct and initialize it
0087  *  @symsize:   the symbol size (number of bits)
0088  *  @gfpoly:    the extended Galois field generator polynomial coefficients,
0089  *      with the 0th coefficient in the low order bit. The polynomial
0090  *      must be primitive;
0091  *  @fcr:   the first consecutive root of the rs code generator polynomial
0092  *      in index form
0093  *  @prim:  primitive element to generate polynomial roots
0094  *  @nroots:    RS code generator polynomial degree (number of roots)
0095  *
0096  * Allocations use GFP_KERNEL.
0097  */
0098 static inline struct rs_control *init_rs(int symsize, int gfpoly, int fcr,
0099                      int prim, int nroots)
0100 {
0101     return init_rs_gfp(symsize, gfpoly, fcr, prim, nroots, GFP_KERNEL);
0102 }
0103 
0104 struct rs_control *init_rs_non_canonical(int symsize, int (*func)(int),
0105                      int fcr, int prim, int nroots);
0106 
0107 /* Release a rs control structure */
0108 void free_rs(struct rs_control *rs);
0109 
0110 /** modulo replacement for galois field arithmetics
0111  *
0112  *  @rs:    Pointer to the RS codec
0113  *  @x:     the value to reduce
0114  *
0115  *  where
0116  *  rs->mm = number of bits per symbol
0117  *  rs->nn = (2^rs->mm) - 1
0118  *
0119  *  Simple arithmetic modulo would return a wrong result for values
0120  *  >= 3 * rs->nn
0121 */
0122 static inline int rs_modnn(struct rs_codec *rs, int x)
0123 {
0124     while (x >= rs->nn) {
0125         x -= rs->nn;
0126         x = (x >> rs->mm) + (x & rs->nn);
0127     }
0128     return x;
0129 }
0130 
0131 #endif