Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * This file contains an ECC algorithm that detects and corrects 1 bit
0004  * errors in a 256 byte block of data.
0005  *
0006  * Copyright © 2008 Koninklijke Philips Electronics NV.
0007  *                  Author: Frans Meulenbroeks
0008  *
0009  * Completely replaces the previous ECC implementation which was written by:
0010  *   Steven J. Hill (sjhill@realitydiluted.com)
0011  *   Thomas Gleixner (tglx@linutronix.de)
0012  *
0013  * Information on how this algorithm works and how it was developed
0014  * can be found in Documentation/driver-api/mtd/nand_ecc.rst
0015  */
0016 
0017 #include <linux/types.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/mtd/nand.h>
0021 #include <linux/mtd/nand-ecc-sw-hamming.h>
0022 #include <linux/slab.h>
0023 #include <asm/byteorder.h>
0024 
0025 /*
0026  * invparity is a 256 byte table that contains the odd parity
0027  * for each byte. So if the number of bits in a byte is even,
0028  * the array element is 1, and when the number of bits is odd
0029  * the array eleemnt is 0.
0030  */
0031 static const char invparity[256] = {
0032     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0033     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0034     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0035     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0036     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0037     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0038     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0039     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0040     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0041     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0042     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0043     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0044     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0045     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0046     0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0047     1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
0048 };
0049 
0050 /*
0051  * bitsperbyte contains the number of bits per byte
0052  * this is only used for testing and repairing parity
0053  * (a precalculated value slightly improves performance)
0054  */
0055 static const char bitsperbyte[256] = {
0056     0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
0057     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
0058     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
0059     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0060     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
0061     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0062     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0063     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
0064     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
0065     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0066     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0067     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
0068     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
0069     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
0070     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
0071     4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
0072 };
0073 
0074 /*
0075  * addressbits is a lookup table to filter out the bits from the xor-ed
0076  * ECC data that identify the faulty location.
0077  * this is only used for repairing parity
0078  * see the comments in nand_ecc_sw_hamming_correct for more details
0079  */
0080 static const char addressbits[256] = {
0081     0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
0082     0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
0083     0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
0084     0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
0085     0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
0086     0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
0087     0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
0088     0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
0089     0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
0090     0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
0091     0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
0092     0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
0093     0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
0094     0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
0095     0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
0096     0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
0097     0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
0098     0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
0099     0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
0100     0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
0101     0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
0102     0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
0103     0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
0104     0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
0105     0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
0106     0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
0107     0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
0108     0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
0109     0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
0110     0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
0111     0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
0112     0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
0113 };
0114 
0115 int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
0116                  unsigned char *code, bool sm_order)
0117 {
0118     const u32 *bp = (uint32_t *)buf;
0119     const u32 eccsize_mult = (step_size == 256) ? 1 : 2;
0120     /* current value in buffer */
0121     u32 cur;
0122     /* rp0..rp17 are the various accumulated parities (per byte) */
0123     u32 rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7, rp8, rp9, rp10, rp11, rp12,
0124         rp13, rp14, rp15, rp16, rp17;
0125     /* Cumulative parity for all data */
0126     u32 par;
0127     /* Cumulative parity at the end of the loop (rp12, rp14, rp16) */
0128     u32 tmppar;
0129     int i;
0130 
0131     par = 0;
0132     rp4 = 0;
0133     rp6 = 0;
0134     rp8 = 0;
0135     rp10 = 0;
0136     rp12 = 0;
0137     rp14 = 0;
0138     rp16 = 0;
0139     rp17 = 0;
0140 
0141     /*
0142      * The loop is unrolled a number of times;
0143      * This avoids if statements to decide on which rp value to update
0144      * Also we process the data by longwords.
0145      * Note: passing unaligned data might give a performance penalty.
0146      * It is assumed that the buffers are aligned.
0147      * tmppar is the cumulative sum of this iteration.
0148      * needed for calculating rp12, rp14, rp16 and par
0149      * also used as a performance improvement for rp6, rp8 and rp10
0150      */
0151     for (i = 0; i < eccsize_mult << 2; i++) {
0152         cur = *bp++;
0153         tmppar = cur;
0154         rp4 ^= cur;
0155         cur = *bp++;
0156         tmppar ^= cur;
0157         rp6 ^= tmppar;
0158         cur = *bp++;
0159         tmppar ^= cur;
0160         rp4 ^= cur;
0161         cur = *bp++;
0162         tmppar ^= cur;
0163         rp8 ^= tmppar;
0164 
0165         cur = *bp++;
0166         tmppar ^= cur;
0167         rp4 ^= cur;
0168         rp6 ^= cur;
0169         cur = *bp++;
0170         tmppar ^= cur;
0171         rp6 ^= cur;
0172         cur = *bp++;
0173         tmppar ^= cur;
0174         rp4 ^= cur;
0175         cur = *bp++;
0176         tmppar ^= cur;
0177         rp10 ^= tmppar;
0178 
0179         cur = *bp++;
0180         tmppar ^= cur;
0181         rp4 ^= cur;
0182         rp6 ^= cur;
0183         rp8 ^= cur;
0184         cur = *bp++;
0185         tmppar ^= cur;
0186         rp6 ^= cur;
0187         rp8 ^= cur;
0188         cur = *bp++;
0189         tmppar ^= cur;
0190         rp4 ^= cur;
0191         rp8 ^= cur;
0192         cur = *bp++;
0193         tmppar ^= cur;
0194         rp8 ^= cur;
0195 
0196         cur = *bp++;
0197         tmppar ^= cur;
0198         rp4 ^= cur;
0199         rp6 ^= cur;
0200         cur = *bp++;
0201         tmppar ^= cur;
0202         rp6 ^= cur;
0203         cur = *bp++;
0204         tmppar ^= cur;
0205         rp4 ^= cur;
0206         cur = *bp++;
0207         tmppar ^= cur;
0208 
0209         par ^= tmppar;
0210         if ((i & 0x1) == 0)
0211             rp12 ^= tmppar;
0212         if ((i & 0x2) == 0)
0213             rp14 ^= tmppar;
0214         if (eccsize_mult == 2 && (i & 0x4) == 0)
0215             rp16 ^= tmppar;
0216     }
0217 
0218     /*
0219      * handle the fact that we use longword operations
0220      * we'll bring rp4..rp14..rp16 back to single byte entities by
0221      * shifting and xoring first fold the upper and lower 16 bits,
0222      * then the upper and lower 8 bits.
0223      */
0224     rp4 ^= (rp4 >> 16);
0225     rp4 ^= (rp4 >> 8);
0226     rp4 &= 0xff;
0227     rp6 ^= (rp6 >> 16);
0228     rp6 ^= (rp6 >> 8);
0229     rp6 &= 0xff;
0230     rp8 ^= (rp8 >> 16);
0231     rp8 ^= (rp8 >> 8);
0232     rp8 &= 0xff;
0233     rp10 ^= (rp10 >> 16);
0234     rp10 ^= (rp10 >> 8);
0235     rp10 &= 0xff;
0236     rp12 ^= (rp12 >> 16);
0237     rp12 ^= (rp12 >> 8);
0238     rp12 &= 0xff;
0239     rp14 ^= (rp14 >> 16);
0240     rp14 ^= (rp14 >> 8);
0241     rp14 &= 0xff;
0242     if (eccsize_mult == 2) {
0243         rp16 ^= (rp16 >> 16);
0244         rp16 ^= (rp16 >> 8);
0245         rp16 &= 0xff;
0246     }
0247 
0248     /*
0249      * we also need to calculate the row parity for rp0..rp3
0250      * This is present in par, because par is now
0251      * rp3 rp3 rp2 rp2 in little endian and
0252      * rp2 rp2 rp3 rp3 in big endian
0253      * as well as
0254      * rp1 rp0 rp1 rp0 in little endian and
0255      * rp0 rp1 rp0 rp1 in big endian
0256      * First calculate rp2 and rp3
0257      */
0258 #ifdef __BIG_ENDIAN
0259     rp2 = (par >> 16);
0260     rp2 ^= (rp2 >> 8);
0261     rp2 &= 0xff;
0262     rp3 = par & 0xffff;
0263     rp3 ^= (rp3 >> 8);
0264     rp3 &= 0xff;
0265 #else
0266     rp3 = (par >> 16);
0267     rp3 ^= (rp3 >> 8);
0268     rp3 &= 0xff;
0269     rp2 = par & 0xffff;
0270     rp2 ^= (rp2 >> 8);
0271     rp2 &= 0xff;
0272 #endif
0273 
0274     /* reduce par to 16 bits then calculate rp1 and rp0 */
0275     par ^= (par >> 16);
0276 #ifdef __BIG_ENDIAN
0277     rp0 = (par >> 8) & 0xff;
0278     rp1 = (par & 0xff);
0279 #else
0280     rp1 = (par >> 8) & 0xff;
0281     rp0 = (par & 0xff);
0282 #endif
0283 
0284     /* finally reduce par to 8 bits */
0285     par ^= (par >> 8);
0286     par &= 0xff;
0287 
0288     /*
0289      * and calculate rp5..rp15..rp17
0290      * note that par = rp4 ^ rp5 and due to the commutative property
0291      * of the ^ operator we can say:
0292      * rp5 = (par ^ rp4);
0293      * The & 0xff seems superfluous, but benchmarking learned that
0294      * leaving it out gives slightly worse results. No idea why, probably
0295      * it has to do with the way the pipeline in pentium is organized.
0296      */
0297     rp5 = (par ^ rp4) & 0xff;
0298     rp7 = (par ^ rp6) & 0xff;
0299     rp9 = (par ^ rp8) & 0xff;
0300     rp11 = (par ^ rp10) & 0xff;
0301     rp13 = (par ^ rp12) & 0xff;
0302     rp15 = (par ^ rp14) & 0xff;
0303     if (eccsize_mult == 2)
0304         rp17 = (par ^ rp16) & 0xff;
0305 
0306     /*
0307      * Finally calculate the ECC bits.
0308      * Again here it might seem that there are performance optimisations
0309      * possible, but benchmarks showed that on the system this is developed
0310      * the code below is the fastest
0311      */
0312     if (sm_order) {
0313         code[0] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
0314               (invparity[rp5] << 5) | (invparity[rp4] << 4) |
0315               (invparity[rp3] << 3) | (invparity[rp2] << 2) |
0316               (invparity[rp1] << 1) | (invparity[rp0]);
0317         code[1] = (invparity[rp15] << 7) | (invparity[rp14] << 6) |
0318               (invparity[rp13] << 5) | (invparity[rp12] << 4) |
0319               (invparity[rp11] << 3) | (invparity[rp10] << 2) |
0320               (invparity[rp9] << 1) | (invparity[rp8]);
0321     } else {
0322         code[1] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
0323               (invparity[rp5] << 5) | (invparity[rp4] << 4) |
0324               (invparity[rp3] << 3) | (invparity[rp2] << 2) |
0325               (invparity[rp1] << 1) | (invparity[rp0]);
0326         code[0] = (invparity[rp15] << 7) | (invparity[rp14] << 6) |
0327               (invparity[rp13] << 5) | (invparity[rp12] << 4) |
0328               (invparity[rp11] << 3) | (invparity[rp10] << 2) |
0329               (invparity[rp9] << 1) | (invparity[rp8]);
0330     }
0331 
0332     if (eccsize_mult == 1)
0333         code[2] =
0334             (invparity[par & 0xf0] << 7) |
0335             (invparity[par & 0x0f] << 6) |
0336             (invparity[par & 0xcc] << 5) |
0337             (invparity[par & 0x33] << 4) |
0338             (invparity[par & 0xaa] << 3) |
0339             (invparity[par & 0x55] << 2) |
0340             3;
0341     else
0342         code[2] =
0343             (invparity[par & 0xf0] << 7) |
0344             (invparity[par & 0x0f] << 6) |
0345             (invparity[par & 0xcc] << 5) |
0346             (invparity[par & 0x33] << 4) |
0347             (invparity[par & 0xaa] << 3) |
0348             (invparity[par & 0x55] << 2) |
0349             (invparity[rp17] << 1) |
0350             (invparity[rp16] << 0);
0351 
0352     return 0;
0353 }
0354 EXPORT_SYMBOL(ecc_sw_hamming_calculate);
0355 
0356 /**
0357  * nand_ecc_sw_hamming_calculate - Calculate 3-byte ECC for 256/512-byte block
0358  * @nand: NAND device
0359  * @buf: Input buffer with raw data
0360  * @code: Output buffer with ECC
0361  */
0362 int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
0363                   const unsigned char *buf, unsigned char *code)
0364 {
0365     struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
0366     unsigned int step_size = nand->ecc.ctx.conf.step_size;
0367     bool sm_order = engine_conf ? engine_conf->sm_order : false;
0368 
0369     return ecc_sw_hamming_calculate(buf, step_size, code, sm_order);
0370 }
0371 EXPORT_SYMBOL(nand_ecc_sw_hamming_calculate);
0372 
0373 int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
0374                unsigned char *calc_ecc, unsigned int step_size,
0375                bool sm_order)
0376 {
0377     const u32 eccsize_mult = step_size >> 8;
0378     unsigned char b0, b1, b2, bit_addr;
0379     unsigned int byte_addr;
0380 
0381     /*
0382      * b0 to b2 indicate which bit is faulty (if any)
0383      * we might need the xor result  more than once,
0384      * so keep them in a local var
0385     */
0386     if (sm_order) {
0387         b0 = read_ecc[0] ^ calc_ecc[0];
0388         b1 = read_ecc[1] ^ calc_ecc[1];
0389     } else {
0390         b0 = read_ecc[1] ^ calc_ecc[1];
0391         b1 = read_ecc[0] ^ calc_ecc[0];
0392     }
0393 
0394     b2 = read_ecc[2] ^ calc_ecc[2];
0395 
0396     /* check if there are any bitfaults */
0397 
0398     /* repeated if statements are slightly more efficient than switch ... */
0399     /* ordered in order of likelihood */
0400 
0401     if ((b0 | b1 | b2) == 0)
0402         return 0;   /* no error */
0403 
0404     if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
0405         (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
0406         ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
0407          (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
0408     /* single bit error */
0409         /*
0410          * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty
0411          * byte, cp 5/3/1 indicate the faulty bit.
0412          * A lookup table (called addressbits) is used to filter
0413          * the bits from the byte they are in.
0414          * A marginal optimisation is possible by having three
0415          * different lookup tables.
0416          * One as we have now (for b0), one for b2
0417          * (that would avoid the >> 1), and one for b1 (with all values
0418          * << 4). However it was felt that introducing two more tables
0419          * hardly justify the gain.
0420          *
0421          * The b2 shift is there to get rid of the lowest two bits.
0422          * We could also do addressbits[b2] >> 1 but for the
0423          * performance it does not make any difference
0424          */
0425         if (eccsize_mult == 1)
0426             byte_addr = (addressbits[b1] << 4) + addressbits[b0];
0427         else
0428             byte_addr = (addressbits[b2 & 0x3] << 8) +
0429                     (addressbits[b1] << 4) + addressbits[b0];
0430         bit_addr = addressbits[b2 >> 2];
0431         /* flip the bit */
0432         buf[byte_addr] ^= (1 << bit_addr);
0433         return 1;
0434 
0435     }
0436     /* count nr of bits; use table lookup, faster than calculating it */
0437     if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
0438         return 1;   /* error in ECC data; no action needed */
0439 
0440     pr_err("%s: uncorrectable ECC error\n", __func__);
0441     return -EBADMSG;
0442 }
0443 EXPORT_SYMBOL(ecc_sw_hamming_correct);
0444 
0445 /**
0446  * nand_ecc_sw_hamming_correct - Detect and correct bit error(s)
0447  * @nand: NAND device
0448  * @buf: Raw data read from the chip
0449  * @read_ecc: ECC bytes read from the chip
0450  * @calc_ecc: ECC calculated from the raw data
0451  *
0452  * Detect and correct up to 1 bit error per 256/512-byte block.
0453  */
0454 int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
0455                 unsigned char *read_ecc,
0456                 unsigned char *calc_ecc)
0457 {
0458     struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
0459     unsigned int step_size = nand->ecc.ctx.conf.step_size;
0460     bool sm_order = engine_conf ? engine_conf->sm_order : false;
0461 
0462     return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, step_size,
0463                       sm_order);
0464 }
0465 EXPORT_SYMBOL(nand_ecc_sw_hamming_correct);
0466 
0467 int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand)
0468 {
0469     struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
0470     struct nand_ecc_sw_hamming_conf *engine_conf;
0471     struct mtd_info *mtd = nanddev_to_mtd(nand);
0472     int ret;
0473 
0474     if (!mtd->ooblayout) {
0475         switch (mtd->oobsize) {
0476         case 8:
0477         case 16:
0478             mtd_set_ooblayout(mtd, nand_get_small_page_ooblayout());
0479             break;
0480         case 64:
0481         case 128:
0482             mtd_set_ooblayout(mtd,
0483                       nand_get_large_page_hamming_ooblayout());
0484             break;
0485         default:
0486             return -ENOTSUPP;
0487         }
0488     }
0489 
0490     conf->engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
0491     conf->algo = NAND_ECC_ALGO_HAMMING;
0492     conf->step_size = nand->ecc.user_conf.step_size;
0493     conf->strength = 1;
0494 
0495     /* Use the strongest configuration by default */
0496     if (conf->step_size != 256 && conf->step_size != 512)
0497         conf->step_size = 256;
0498 
0499     engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL);
0500     if (!engine_conf)
0501         return -ENOMEM;
0502 
0503     ret = nand_ecc_init_req_tweaking(&engine_conf->req_ctx, nand);
0504     if (ret)
0505         goto free_engine_conf;
0506 
0507     engine_conf->code_size = 3;
0508     engine_conf->calc_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
0509     engine_conf->code_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
0510     if (!engine_conf->calc_buf || !engine_conf->code_buf) {
0511         ret = -ENOMEM;
0512         goto free_bufs;
0513     }
0514 
0515     nand->ecc.ctx.priv = engine_conf;
0516     nand->ecc.ctx.nsteps = mtd->writesize / conf->step_size;
0517     nand->ecc.ctx.total = nand->ecc.ctx.nsteps * engine_conf->code_size;
0518 
0519     return 0;
0520 
0521 free_bufs:
0522     nand_ecc_cleanup_req_tweaking(&engine_conf->req_ctx);
0523     kfree(engine_conf->calc_buf);
0524     kfree(engine_conf->code_buf);
0525 free_engine_conf:
0526     kfree(engine_conf);
0527 
0528     return ret;
0529 }
0530 EXPORT_SYMBOL(nand_ecc_sw_hamming_init_ctx);
0531 
0532 void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand)
0533 {
0534     struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
0535 
0536     if (engine_conf) {
0537         nand_ecc_cleanup_req_tweaking(&engine_conf->req_ctx);
0538         kfree(engine_conf->calc_buf);
0539         kfree(engine_conf->code_buf);
0540         kfree(engine_conf);
0541     }
0542 }
0543 EXPORT_SYMBOL(nand_ecc_sw_hamming_cleanup_ctx);
0544 
0545 static int nand_ecc_sw_hamming_prepare_io_req(struct nand_device *nand,
0546                           struct nand_page_io_req *req)
0547 {
0548     struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
0549     struct mtd_info *mtd = nanddev_to_mtd(nand);
0550     int eccsize = nand->ecc.ctx.conf.step_size;
0551     int eccbytes = engine_conf->code_size;
0552     int eccsteps = nand->ecc.ctx.nsteps;
0553     int total = nand->ecc.ctx.total;
0554     u8 *ecccalc = engine_conf->calc_buf;
0555     const u8 *data;
0556     int i;
0557 
0558     /* Nothing to do for a raw operation */
0559     if (req->mode == MTD_OPS_RAW)
0560         return 0;
0561 
0562     /* This engine does not provide BBM/free OOB bytes protection */
0563     if (!req->datalen)
0564         return 0;
0565 
0566     nand_ecc_tweak_req(&engine_conf->req_ctx, req);
0567 
0568     /* No more preparation for page read */
0569     if (req->type == NAND_PAGE_READ)
0570         return 0;
0571 
0572     /* Preparation for page write: derive the ECC bytes and place them */
0573     for (i = 0, data = req->databuf.out;
0574          eccsteps;
0575          eccsteps--, i += eccbytes, data += eccsize)
0576         nand_ecc_sw_hamming_calculate(nand, data, &ecccalc[i]);
0577 
0578     return mtd_ooblayout_set_eccbytes(mtd, ecccalc, (void *)req->oobbuf.out,
0579                       0, total);
0580 }
0581 
0582 static int nand_ecc_sw_hamming_finish_io_req(struct nand_device *nand,
0583                          struct nand_page_io_req *req)
0584 {
0585     struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
0586     struct mtd_info *mtd = nanddev_to_mtd(nand);
0587     int eccsize = nand->ecc.ctx.conf.step_size;
0588     int total = nand->ecc.ctx.total;
0589     int eccbytes = engine_conf->code_size;
0590     int eccsteps = nand->ecc.ctx.nsteps;
0591     u8 *ecccalc = engine_conf->calc_buf;
0592     u8 *ecccode = engine_conf->code_buf;
0593     unsigned int max_bitflips = 0;
0594     u8 *data = req->databuf.in;
0595     int i, ret;
0596 
0597     /* Nothing to do for a raw operation */
0598     if (req->mode == MTD_OPS_RAW)
0599         return 0;
0600 
0601     /* This engine does not provide BBM/free OOB bytes protection */
0602     if (!req->datalen)
0603         return 0;
0604 
0605     /* No more preparation for page write */
0606     if (req->type == NAND_PAGE_WRITE) {
0607         nand_ecc_restore_req(&engine_conf->req_ctx, req);
0608         return 0;
0609     }
0610 
0611     /* Finish a page read: retrieve the (raw) ECC bytes*/
0612     ret = mtd_ooblayout_get_eccbytes(mtd, ecccode, req->oobbuf.in, 0,
0613                      total);
0614     if (ret)
0615         return ret;
0616 
0617     /* Calculate the ECC bytes */
0618     for (i = 0; eccsteps; eccsteps--, i += eccbytes, data += eccsize)
0619         nand_ecc_sw_hamming_calculate(nand, data, &ecccalc[i]);
0620 
0621     /* Finish a page read: compare and correct */
0622     for (eccsteps = nand->ecc.ctx.nsteps, i = 0, data = req->databuf.in;
0623          eccsteps;
0624          eccsteps--, i += eccbytes, data += eccsize) {
0625         int stat =  nand_ecc_sw_hamming_correct(nand, data,
0626                             &ecccode[i],
0627                             &ecccalc[i]);
0628         if (stat < 0) {
0629             mtd->ecc_stats.failed++;
0630         } else {
0631             mtd->ecc_stats.corrected += stat;
0632             max_bitflips = max_t(unsigned int, max_bitflips, stat);
0633         }
0634     }
0635 
0636     nand_ecc_restore_req(&engine_conf->req_ctx, req);
0637 
0638     return max_bitflips;
0639 }
0640 
0641 static struct nand_ecc_engine_ops nand_ecc_sw_hamming_engine_ops = {
0642     .init_ctx = nand_ecc_sw_hamming_init_ctx,
0643     .cleanup_ctx = nand_ecc_sw_hamming_cleanup_ctx,
0644     .prepare_io_req = nand_ecc_sw_hamming_prepare_io_req,
0645     .finish_io_req = nand_ecc_sw_hamming_finish_io_req,
0646 };
0647 
0648 static struct nand_ecc_engine nand_ecc_sw_hamming_engine = {
0649     .ops = &nand_ecc_sw_hamming_engine_ops,
0650 };
0651 
0652 struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void)
0653 {
0654     return &nand_ecc_sw_hamming_engine;
0655 }
0656 EXPORT_SYMBOL(nand_ecc_sw_hamming_get_engine);
0657 
0658 MODULE_LICENSE("GPL");
0659 MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
0660 MODULE_DESCRIPTION("NAND software Hamming ECC support");