hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/lib/bch.c
....@@ -23,15 +23,15 @@
2323 * This library provides runtime configurable encoding/decoding of binary
2424 * Bose-Chaudhuri-Hocquenghem (BCH) codes.
2525 *
26
- * Call init_bch to get a pointer to a newly allocated bch_control structure for
26
+ * Call bch_init to get a pointer to a newly allocated bch_control structure for
2727 * the given m (Galois field order), t (error correction capability) and
2828 * (optional) primitive polynomial parameters.
2929 *
30
- * Call encode_bch to compute and store ecc parity bytes to a given buffer.
31
- * Call decode_bch to detect and locate errors in received data.
30
+ * Call bch_encode to compute and store ecc parity bytes to a given buffer.
31
+ * Call bch_decode to detect and locate errors in received data.
3232 *
3333 * On systems supporting hw BCH features, intermediate results may be provided
34
- * to decode_bch in order to skip certain steps. See decode_bch() documentation
34
+ * to bch_decode in order to skip certain steps. See bch_decode() documentation
3535 * for details.
3636 *
3737 * Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of
....@@ -102,7 +102,7 @@
102102 */
103103 struct gf_poly {
104104 unsigned int deg; /* polynomial degree */
105
- unsigned int c[0]; /* polynomial terms */
105
+ unsigned int c[]; /* polynomial terms */
106106 };
107107
108108 /* given its degree, compute a polynomial size in bytes */
....@@ -114,10 +114,53 @@
114114 unsigned int c[2];
115115 };
116116
117
+static u8 swap_bits_table[] = {
118
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
119
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
120
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
121
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
122
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
123
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
124
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
125
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
126
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
127
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
128
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
129
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
130
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
131
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
132
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
133
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
134
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
135
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
136
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
137
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
138
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
139
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
140
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
141
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
142
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
143
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
144
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
145
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
146
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
147
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
148
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
149
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
150
+};
151
+
152
+static u8 swap_bits(struct bch_control *bch, u8 in)
153
+{
154
+ if (!bch->swap_bits)
155
+ return in;
156
+
157
+ return swap_bits_table[in];
158
+}
159
+
117160 /*
118
- * same as encode_bch(), but process input data one byte at a time
161
+ * same as bch_encode(), but process input data one byte at a time
119162 */
120
-static void encode_bch_unaligned(struct bch_control *bch,
163
+static void bch_encode_unaligned(struct bch_control *bch,
121164 const unsigned char *data, unsigned int len,
122165 uint32_t *ecc)
123166 {
....@@ -126,7 +169,9 @@
126169 const int l = BCH_ECC_WORDS(bch)-1;
127170
128171 while (len--) {
129
- p = bch->mod8_tab + (l+1)*(((ecc[0] >> 24)^(*data++)) & 0xff);
172
+ u8 tmp = swap_bits(bch, *data++);
173
+
174
+ p = bch->mod8_tab + (l+1)*(((ecc[0] >> 24)^(tmp)) & 0xff);
130175
131176 for (i = 0; i < l; i++)
132177 ecc[i] = ((ecc[i] << 8)|(ecc[i+1] >> 24))^(*p++);
....@@ -145,10 +190,16 @@
145190 unsigned int i, nwords = BCH_ECC_WORDS(bch)-1;
146191
147192 for (i = 0; i < nwords; i++, src += 4)
148
- dst[i] = (src[0] << 24)|(src[1] << 16)|(src[2] << 8)|src[3];
193
+ dst[i] = ((u32)swap_bits(bch, src[0]) << 24) |
194
+ ((u32)swap_bits(bch, src[1]) << 16) |
195
+ ((u32)swap_bits(bch, src[2]) << 8) |
196
+ swap_bits(bch, src[3]);
149197
150198 memcpy(pad, src, BCH_ECC_BYTES(bch)-4*nwords);
151
- dst[nwords] = (pad[0] << 24)|(pad[1] << 16)|(pad[2] << 8)|pad[3];
199
+ dst[nwords] = ((u32)swap_bits(bch, pad[0]) << 24) |
200
+ ((u32)swap_bits(bch, pad[1]) << 16) |
201
+ ((u32)swap_bits(bch, pad[2]) << 8) |
202
+ swap_bits(bch, pad[3]);
152203 }
153204
154205 /*
....@@ -161,20 +212,20 @@
161212 unsigned int i, nwords = BCH_ECC_WORDS(bch)-1;
162213
163214 for (i = 0; i < nwords; i++) {
164
- *dst++ = (src[i] >> 24);
165
- *dst++ = (src[i] >> 16) & 0xff;
166
- *dst++ = (src[i] >> 8) & 0xff;
167
- *dst++ = (src[i] >> 0) & 0xff;
215
+ *dst++ = swap_bits(bch, src[i] >> 24);
216
+ *dst++ = swap_bits(bch, src[i] >> 16);
217
+ *dst++ = swap_bits(bch, src[i] >> 8);
218
+ *dst++ = swap_bits(bch, src[i]);
168219 }
169
- pad[0] = (src[nwords] >> 24);
170
- pad[1] = (src[nwords] >> 16) & 0xff;
171
- pad[2] = (src[nwords] >> 8) & 0xff;
172
- pad[3] = (src[nwords] >> 0) & 0xff;
220
+ pad[0] = swap_bits(bch, src[nwords] >> 24);
221
+ pad[1] = swap_bits(bch, src[nwords] >> 16);
222
+ pad[2] = swap_bits(bch, src[nwords] >> 8);
223
+ pad[3] = swap_bits(bch, src[nwords]);
173224 memcpy(dst, pad, BCH_ECC_BYTES(bch)-4*nwords);
174225 }
175226
176227 /**
177
- * encode_bch - calculate BCH ecc parity of data
228
+ * bch_encode - calculate BCH ecc parity of data
178229 * @bch: BCH control structure
179230 * @data: data to encode
180231 * @len: data length in bytes
....@@ -187,7 +238,7 @@
187238 * The exact number of computed ecc parity bits is given by member @ecc_bits of
188239 * @bch; it may be less than m*t for large values of t.
189240 */
190
-void encode_bch(struct bch_control *bch, const uint8_t *data,
241
+void bch_encode(struct bch_control *bch, const uint8_t *data,
191242 unsigned int len, uint8_t *ecc)
192243 {
193244 const unsigned int l = BCH_ECC_WORDS(bch)-1;
....@@ -215,7 +266,7 @@
215266 m = ((unsigned long)data) & 3;
216267 if (m) {
217268 mlen = (len < (4-m)) ? len : 4-m;
218
- encode_bch_unaligned(bch, data, mlen, bch->ecc_buf);
269
+ bch_encode_unaligned(bch, data, mlen, bch->ecc_buf);
219270 data += mlen;
220271 len -= mlen;
221272 }
....@@ -240,7 +291,13 @@
240291 */
241292 while (mlen--) {
242293 /* input data is read in big-endian format */
243
- w = r[0]^cpu_to_be32(*pdata++);
294
+ w = cpu_to_be32(*pdata++);
295
+ if (bch->swap_bits)
296
+ w = (u32)swap_bits(bch, w) |
297
+ ((u32)swap_bits(bch, w >> 8) << 8) |
298
+ ((u32)swap_bits(bch, w >> 16) << 16) |
299
+ ((u32)swap_bits(bch, w >> 24) << 24);
300
+ w ^= r[0];
244301 p0 = tab0 + (l+1)*((w >> 0) & 0xff);
245302 p1 = tab1 + (l+1)*((w >> 8) & 0xff);
246303 p2 = tab2 + (l+1)*((w >> 16) & 0xff);
....@@ -255,13 +312,13 @@
255312
256313 /* process last unaligned bytes */
257314 if (len)
258
- encode_bch_unaligned(bch, data, len, bch->ecc_buf);
315
+ bch_encode_unaligned(bch, data, len, bch->ecc_buf);
259316
260317 /* store ecc parity bytes into original parity buffer */
261318 if (ecc)
262319 store_ecc8(bch, ecc, bch->ecc_buf);
263320 }
264
-EXPORT_SYMBOL_GPL(encode_bch);
321
+EXPORT_SYMBOL_GPL(bch_encode);
265322
266323 static inline int modulo(struct bch_control *bch, unsigned int v)
267324 {
....@@ -952,7 +1009,7 @@
9521009 #endif /* USE_CHIEN_SEARCH */
9531010
9541011 /**
955
- * decode_bch - decode received codeword and find bit error locations
1012
+ * bch_decode - decode received codeword and find bit error locations
9561013 * @bch: BCH control structure
9571014 * @data: received data, ignored if @calc_ecc is provided
9581015 * @len: data length in bytes, must always be provided
....@@ -966,22 +1023,22 @@
9661023 * invalid parameters were provided
9671024 *
9681025 * Depending on the available hw BCH support and the need to compute @calc_ecc
969
- * separately (using encode_bch()), this function should be called with one of
1026
+ * separately (using bch_encode()), this function should be called with one of
9701027 * the following parameter configurations -
9711028 *
9721029 * by providing @data and @recv_ecc only:
973
- * decode_bch(@bch, @data, @len, @recv_ecc, NULL, NULL, @errloc)
1030
+ * bch_decode(@bch, @data, @len, @recv_ecc, NULL, NULL, @errloc)
9741031 *
9751032 * by providing @recv_ecc and @calc_ecc:
976
- * decode_bch(@bch, NULL, @len, @recv_ecc, @calc_ecc, NULL, @errloc)
1033
+ * bch_decode(@bch, NULL, @len, @recv_ecc, @calc_ecc, NULL, @errloc)
9771034 *
9781035 * by providing ecc = recv_ecc XOR calc_ecc:
979
- * decode_bch(@bch, NULL, @len, NULL, ecc, NULL, @errloc)
1036
+ * bch_decode(@bch, NULL, @len, NULL, ecc, NULL, @errloc)
9801037 *
9811038 * by providing syndrome results @syn:
982
- * decode_bch(@bch, NULL, @len, NULL, NULL, @syn, @errloc)
1039
+ * bch_decode(@bch, NULL, @len, NULL, NULL, @syn, @errloc)
9831040 *
984
- * Once decode_bch() has successfully returned with a positive value, error
1041
+ * Once bch_decode() has successfully returned with a positive value, error
9851042 * locations returned in array @errloc should be interpreted as follows -
9861043 *
9871044 * if (errloc[n] >= 8*len), then n-th error is located in ecc (no need for
....@@ -993,7 +1050,7 @@
9931050 * Note that this function does not perform any data correction by itself, it
9941051 * merely indicates error locations.
9951052 */
996
-int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len,
1053
+int bch_decode(struct bch_control *bch, const uint8_t *data, unsigned int len,
9971054 const uint8_t *recv_ecc, const uint8_t *calc_ecc,
9981055 const unsigned int *syn, unsigned int *errloc)
9991056 {
....@@ -1012,7 +1069,7 @@
10121069 /* compute received data ecc into an internal buffer */
10131070 if (!data || !recv_ecc)
10141071 return -EINVAL;
1015
- encode_bch(bch, data, len, NULL);
1072
+ bch_encode(bch, data, len, NULL);
10161073 } else {
10171074 /* load provided calculated ecc */
10181075 load_ecc8(bch, bch->ecc_buf, calc_ecc);
....@@ -1048,12 +1105,14 @@
10481105 break;
10491106 }
10501107 errloc[i] = nbits-1-errloc[i];
1051
- errloc[i] = (errloc[i] & ~7)|(7-(errloc[i] & 7));
1108
+ if (!bch->swap_bits)
1109
+ errloc[i] = (errloc[i] & ~7) |
1110
+ (7-(errloc[i] & 7));
10521111 }
10531112 }
10541113 return (err >= 0) ? err : -EBADMSG;
10551114 }
1056
-EXPORT_SYMBOL_GPL(decode_bch);
1115
+EXPORT_SYMBOL_GPL(bch_decode);
10571116
10581117 /*
10591118 * generate Galois field lookup tables
....@@ -1236,27 +1295,29 @@
12361295 }
12371296
12381297 /**
1239
- * init_bch - initialize a BCH encoder/decoder
1298
+ * bch_init - initialize a BCH encoder/decoder
12401299 * @m: Galois field order, should be in the range 5-15
12411300 * @t: maximum error correction capability, in bits
12421301 * @prim_poly: user-provided primitive polynomial (or 0 to use default)
1302
+ * @swap_bits: swap bits within data and syndrome bytes
12431303 *
12441304 * Returns:
12451305 * a newly allocated BCH control structure if successful, NULL otherwise
12461306 *
12471307 * This initialization can take some time, as lookup tables are built for fast
12481308 * encoding/decoding; make sure not to call this function from a time critical
1249
- * path. Usually, init_bch() should be called on module/driver init and
1250
- * free_bch() should be called to release memory on exit.
1309
+ * path. Usually, bch_init() should be called on module/driver init and
1310
+ * bch_free() should be called to release memory on exit.
12511311 *
12521312 * You may provide your own primitive polynomial of degree @m in argument
1253
- * @prim_poly, or let init_bch() use its default polynomial.
1313
+ * @prim_poly, or let bch_init() use its default polynomial.
12541314 *
1255
- * Once init_bch() has successfully returned a pointer to a newly allocated
1315
+ * Once bch_init() has successfully returned a pointer to a newly allocated
12561316 * BCH control structure, ecc length in bytes is given by member @ecc_bytes of
12571317 * the structure.
12581318 */
1259
-struct bch_control *init_bch(int m, int t, unsigned int prim_poly)
1319
+struct bch_control *bch_init(int m, int t, unsigned int prim_poly,
1320
+ bool swap_bits)
12601321 {
12611322 int err = 0;
12621323 unsigned int i, words;
....@@ -1321,6 +1382,7 @@
13211382 bch->syn = bch_alloc(2*t*sizeof(*bch->syn), &err);
13221383 bch->cache = bch_alloc(2*t*sizeof(*bch->cache), &err);
13231384 bch->elp = bch_alloc((t+1)*sizeof(struct gf_poly_deg1), &err);
1385
+ bch->swap_bits = swap_bits;
13241386
13251387 for (i = 0; i < ARRAY_SIZE(bch->poly_2t); i++)
13261388 bch->poly_2t[i] = bch_alloc(GF_POLY_SZ(2*t), &err);
....@@ -1347,16 +1409,16 @@
13471409 return bch;
13481410
13491411 fail:
1350
- free_bch(bch);
1412
+ bch_free(bch);
13511413 return NULL;
13521414 }
1353
-EXPORT_SYMBOL_GPL(init_bch);
1415
+EXPORT_SYMBOL_GPL(bch_init);
13541416
13551417 /**
1356
- * free_bch - free the BCH control structure
1418
+ * bch_free - free the BCH control structure
13571419 * @bch: BCH control structure to release
13581420 */
1359
-void free_bch(struct bch_control *bch)
1421
+void bch_free(struct bch_control *bch)
13601422 {
13611423 unsigned int i;
13621424
....@@ -1377,7 +1439,7 @@
13771439 kfree(bch);
13781440 }
13791441 }
1380
-EXPORT_SYMBOL_GPL(free_bch);
1442
+EXPORT_SYMBOL_GPL(bch_free);
13811443
13821444 MODULE_LICENSE("GPL");
13831445 MODULE_AUTHOR("Ivan Djelic <ivan.djelic@parrot.com>");