162306a36Sopenharmony_ci==========================================
262306a36Sopenharmony_ciReed-Solomon Library Programming Interface
362306a36Sopenharmony_ci==========================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci:Author: Thomas Gleixner
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciIntroduction
862306a36Sopenharmony_ci============
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciThe generic Reed-Solomon Library provides encoding, decoding and error
1162306a36Sopenharmony_cicorrection functions.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciReed-Solomon codes are used in communication and storage applications to
1462306a36Sopenharmony_ciensure data integrity.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciThis documentation is provided for developers who want to utilize the
1762306a36Sopenharmony_cifunctions provided by the library.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciKnown Bugs And Assumptions
2062306a36Sopenharmony_ci==========================
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciNone.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciUsage
2562306a36Sopenharmony_ci=====
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciThis chapter provides examples of how to use the library.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciInitializing
3062306a36Sopenharmony_ci------------
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciThe init function init_rs returns a pointer to an rs decoder structure,
3362306a36Sopenharmony_ciwhich holds the necessary information for encoding, decoding and error
3462306a36Sopenharmony_cicorrection with the given polynomial. It either uses an existing
3562306a36Sopenharmony_cimatching decoder or creates a new one. On creation all the lookup tables
3662306a36Sopenharmony_cifor fast en/decoding are created. The function may take a while, so make
3762306a36Sopenharmony_cisure not to call it in critical code paths.
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci::
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci    /* the Reed Solomon control structure */
4262306a36Sopenharmony_ci    static struct rs_control *rs_decoder;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci    /* Symbolsize is 10 (bits)
4562306a36Sopenharmony_ci     * Primitive polynomial is x^10+x^3+1
4662306a36Sopenharmony_ci     * first consecutive root is 0
4762306a36Sopenharmony_ci     * primitive element to generate roots = 1
4862306a36Sopenharmony_ci     * generator polynomial degree (number of roots) = 6
4962306a36Sopenharmony_ci     */
5062306a36Sopenharmony_ci    rs_decoder = init_rs (10, 0x409, 0, 1, 6);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ciEncoding
5462306a36Sopenharmony_ci--------
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciThe encoder calculates the Reed-Solomon code over the given data length
5762306a36Sopenharmony_ciand stores the result in the parity buffer. Note that the parity buffer
5862306a36Sopenharmony_cimust be initialized before calling the encoder.
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciThe expanded data can be inverted on the fly by providing a non-zero
6162306a36Sopenharmony_ciinversion mask. The expanded data is XOR'ed with the mask. This is used
6262306a36Sopenharmony_cie.g. for FLASH ECC, where the all 0xFF is inverted to an all 0x00. The
6362306a36Sopenharmony_ciReed-Solomon code for all 0x00 is all 0x00. The code is inverted before
6462306a36Sopenharmony_cistoring to FLASH so it is 0xFF too. This prevents that reading from an
6562306a36Sopenharmony_cierased FLASH results in ECC errors.
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciThe databytes are expanded to the given symbol size on the fly. There is
6862306a36Sopenharmony_cino support for encoding continuous bitstreams with a symbol size != 8 at
6962306a36Sopenharmony_cithe moment. If it is necessary it should be not a big deal to implement
7062306a36Sopenharmony_cisuch functionality.
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci::
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci    /* Parity buffer. Size = number of roots */
7562306a36Sopenharmony_ci    uint16_t par[6];
7662306a36Sopenharmony_ci    /* Initialize the parity buffer */
7762306a36Sopenharmony_ci    memset(par, 0, sizeof(par));
7862306a36Sopenharmony_ci    /* Encode 512 byte in data8. Store parity in buffer par */
7962306a36Sopenharmony_ci    encode_rs8 (rs_decoder, data8, 512, par, 0);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ciDecoding
8362306a36Sopenharmony_ci--------
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciThe decoder calculates the syndrome over the given data length and the
8662306a36Sopenharmony_cireceived parity symbols and corrects errors in the data.
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciIf a syndrome is available from a hardware decoder then the syndrome
8962306a36Sopenharmony_cicalculation is skipped.
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciThe correction of the data buffer can be suppressed by providing a
9262306a36Sopenharmony_cicorrection pattern buffer and an error location buffer to the decoder.
9362306a36Sopenharmony_ciThe decoder stores the calculated error location and the correction
9462306a36Sopenharmony_cibitmask in the given buffers. This is useful for hardware decoders which
9562306a36Sopenharmony_ciuse a weird bit ordering scheme.
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciThe databytes are expanded to the given symbol size on the fly. There is
9862306a36Sopenharmony_cino support for decoding continuous bitstreams with a symbolsize != 8 at
9962306a36Sopenharmony_cithe moment. If it is necessary it should be not a big deal to implement
10062306a36Sopenharmony_cisuch functionality.
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciDecoding with syndrome calculation, direct data correction
10362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci::
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci    /* Parity buffer. Size = number of roots */
10862306a36Sopenharmony_ci    uint16_t par[6];
10962306a36Sopenharmony_ci    uint8_t  data[512];
11062306a36Sopenharmony_ci    int numerr;
11162306a36Sopenharmony_ci    /* Receive data */
11262306a36Sopenharmony_ci    .....
11362306a36Sopenharmony_ci    /* Receive parity */
11462306a36Sopenharmony_ci    .....
11562306a36Sopenharmony_ci    /* Decode 512 byte in data8.*/
11662306a36Sopenharmony_ci    numerr = decode_rs8 (rs_decoder, data8, par, 512, NULL, 0, NULL, 0, NULL);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciDecoding with syndrome given by hardware decoder, direct data correction
12062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci::
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci    /* Parity buffer. Size = number of roots */
12562306a36Sopenharmony_ci    uint16_t par[6], syn[6];
12662306a36Sopenharmony_ci    uint8_t  data[512];
12762306a36Sopenharmony_ci    int numerr;
12862306a36Sopenharmony_ci    /* Receive data */
12962306a36Sopenharmony_ci    .....
13062306a36Sopenharmony_ci    /* Receive parity */
13162306a36Sopenharmony_ci    .....
13262306a36Sopenharmony_ci    /* Get syndrome from hardware decoder */
13362306a36Sopenharmony_ci    .....
13462306a36Sopenharmony_ci    /* Decode 512 byte in data8.*/
13562306a36Sopenharmony_ci    numerr = decode_rs8 (rs_decoder, data8, par, 512, syn, 0, NULL, 0, NULL);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciDecoding with syndrome given by hardware decoder, no direct data correction.
13962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ciNote: It's not necessary to give data and received parity to the
14262306a36Sopenharmony_cidecoder.
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci::
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci    /* Parity buffer. Size = number of roots */
14762306a36Sopenharmony_ci    uint16_t par[6], syn[6], corr[8];
14862306a36Sopenharmony_ci    uint8_t  data[512];
14962306a36Sopenharmony_ci    int numerr, errpos[8];
15062306a36Sopenharmony_ci    /* Receive data */
15162306a36Sopenharmony_ci    .....
15262306a36Sopenharmony_ci    /* Receive parity */
15362306a36Sopenharmony_ci    .....
15462306a36Sopenharmony_ci    /* Get syndrome from hardware decoder */
15562306a36Sopenharmony_ci    .....
15662306a36Sopenharmony_ci    /* Decode 512 byte in data8.*/
15762306a36Sopenharmony_ci    numerr = decode_rs8 (rs_decoder, NULL, NULL, 512, syn, 0, errpos, 0, corr);
15862306a36Sopenharmony_ci    for (i = 0; i < numerr; i++) {
15962306a36Sopenharmony_ci        do_error_correction_in_your_buffer(errpos[i], corr[i]);
16062306a36Sopenharmony_ci    }
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ciCleanup
16462306a36Sopenharmony_ci-------
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciThe function free_rs frees the allocated resources, if the caller is
16762306a36Sopenharmony_cithe last user of the decoder.
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci::
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci    /* Release resources */
17262306a36Sopenharmony_ci    free_rs(rs_decoder);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ciStructures
17662306a36Sopenharmony_ci==========
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciThis chapter contains the autogenerated documentation of the structures
17962306a36Sopenharmony_ciwhich are used in the Reed-Solomon Library and are relevant for a
18062306a36Sopenharmony_cideveloper.
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci.. kernel-doc:: include/linux/rslib.h
18362306a36Sopenharmony_ci   :internal:
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ciPublic Functions Provided
18662306a36Sopenharmony_ci=========================
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciThis chapter contains the autogenerated documentation of the
18962306a36Sopenharmony_ciReed-Solomon functions which are exported.
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci.. kernel-doc:: lib/reed_solomon/reed_solomon.c
19262306a36Sopenharmony_ci   :export:
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciCredits
19562306a36Sopenharmony_ci=======
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ciThe library code for encoding and decoding was written by Phil Karn.
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci::
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci            Copyright 2002, Phil Karn, KA9Q
20262306a36Sopenharmony_ci            May be used under the terms of the GNU General Public License (GPL)
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciThe wrapper functions and interfaces are written by Thomas Gleixner.
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciMany users have provided bugfixes, improvements and helping hands for
20862306a36Sopenharmony_citesting. Thanks a lot.
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciThe following people have contributed to this document:
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ciThomas Gleixner\ tglx@linutronix.de
213