blob: c4bec37e73ebbd60d023530e36c9c8aca927d28f [file] [log] [blame]
David Woodhouse04459d72006-10-22 02:18:48 +01001/* Error correction for CAFÉ NAND controller
2 *
3 * © 2006 Marvell, Inc.
4 * Author: Tom Chiou
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/errno.h>
23
24static unsigned short gf4096_mul(unsigned short, unsigned short);
25static unsigned short gf64_mul(unsigned short, unsigned short);
26static unsigned short gf4096_inv(unsigned short);
27static unsigned short err_pos(unsigned short);
28static void find_4bit_err_coefs(unsigned short, unsigned short, unsigned short,
29 unsigned short, unsigned short, unsigned short,
30 unsigned short, unsigned short, unsigned short *);
31static void zero_4x5_col3(unsigned short[4][5]);
32static void zero_4x5_col2(unsigned short[4][5]);
33static void zero_4x5_col1(unsigned short[4][5]);
34static void swap_4x5_rows(unsigned short[4][5], int, int, int);
35static void swap_2x3_rows(unsigned short m[2][3]);
36static void solve_4x5(unsigned short m[4][5], unsigned short *, int *);
37static void sort_coefs(int *, unsigned short *, int);
38static void find_4bit_err_pats(unsigned short, unsigned short, unsigned short,
39 unsigned short, unsigned short, unsigned short,
40 unsigned short, unsigned short, unsigned short *);
41static void find_3bit_err_coefs(unsigned short, unsigned short, unsigned short,
42 unsigned short, unsigned short, unsigned short,
43 unsigned short *);
44static void zero_3x4_col2(unsigned short[3][4]);
45static void zero_3x4_col1(unsigned short[3][4]);
46static void swap_3x4_rows(unsigned short[3][4], int, int, int);
47static void solve_3x4(unsigned short[3][4], unsigned short *, int *);
48static void find_3bit_err_pats(unsigned short, unsigned short, unsigned short,
49 unsigned short, unsigned short, unsigned short,
50 unsigned short *);
51
52static void find_2bit_err_pats(unsigned short, unsigned short, unsigned short,
53 unsigned short, unsigned short *);
54static void find_2x2_soln(unsigned short, unsigned short, unsigned short,
55 unsigned short, unsigned short, unsigned short,
56 unsigned short *);
57static void solve_2x3(unsigned short[2][3], unsigned short *);
58static int chk_no_err_only(unsigned short *, unsigned short *);
59static int chk_1_err_only(unsigned short *, unsigned short *);
60static int chk_2_err_only(unsigned short *, unsigned short *);
61static int chk_3_err_only(unsigned short *, unsigned short *);
62static int chk_4_err_only(unsigned short *, unsigned short *);
63
64static unsigned short gf64_mul(unsigned short a, unsigned short b)
65{
66 unsigned short tmp1, tmp2, tmp3, tmp4, tmp5;
67 unsigned short c_bit0, c_bit1, c_bit2, c_bit3, c_bit4, c_bit5, c;
68
69 tmp1 = ((a) ^ (a >> 5));
70 tmp2 = ((a >> 4) ^ (a >> 5));
71 tmp3 = ((a >> 3) ^ (a >> 4));
72 tmp4 = ((a >> 2) ^ (a >> 3));
73 tmp5 = ((a >> 1) ^ (a >> 2));
74
75 c_bit0 = ((a & b) ^ ((a >> 5) & (b >> 1)) ^ ((a >> 4) & (b >> 2)) ^
76 ((a >> 3) & (b >> 3)) ^ ((a >> 2) & (b >> 4)) ^ ((a >> 1) & (b >> 5))) & 0x1;
77
78 c_bit1 = (((a >> 1) & b) ^ (tmp1 & (b >> 1)) ^ (tmp2 & (b >> 2)) ^
79 (tmp3 & (b >> 3)) ^ (tmp4 & (b >> 4)) ^ (tmp5 & (b >> 5))) & 0x1;
80
81 c_bit2 = (((a >> 2) & b) ^ ((a >> 1) & (b >> 1)) ^ (tmp1 & (b >> 2)) ^
82 (tmp2 & (b >> 3)) ^ (tmp3 & (b >> 4)) ^ (tmp4 & (b >> 5))) & 0x1;
83
84 c_bit3 = (((a >> 3) & b) ^ ((a >> 2) & (b >> 1)) ^ ((a >> 1) & (b >> 2)) ^
85 (tmp1 & (b >> 3)) ^ (tmp2 & (b >> 4)) ^ (tmp3 & (b >> 5))) & 0x1;
86
87 c_bit4 = (((a >> 4) & b) ^ ((a >> 3) & (b >> 1)) ^ ((a >> 2) & (b >> 2)) ^
88 ((a >> 1) & (b >> 3)) ^ (tmp1 & (b >> 4)) ^ (tmp2 & (b >> 5))) & 0x1;
89
90 c_bit5 = (((a >> 5) & b) ^ ((a >> 4) & (b >> 1)) ^ ((a >> 3) & (b >> 2)) ^
91 ((a >> 2) & (b >> 3)) ^ ((a >> 1) & (b >> 4)) ^ (tmp1 & (b >> 5))) & 0x1;
92
93 c = c_bit0 | (c_bit1 << 1) | (c_bit2 << 2) | (c_bit3 << 3) | (c_bit4 << 4) | (c_bit5 << 5);
94
95 return c;
96}
97
98static unsigned short gf4096_mul(unsigned short a, unsigned short b)
99{
100 unsigned short ah, al, bh, bl, alxah, blxbh, ablh, albl, ahbh, ahbhB, c;
101
102 ah = (a >> 6) & 0x3f;
103 al = a & 0x3f;
104 bh = (b >> 6) & 0x3f;
105 bl = b & 0x3f;
106 alxah = al ^ ah;
107 blxbh = bl ^ bh;
108
109 ablh = gf64_mul(alxah, blxbh);
110 albl = gf64_mul(al, bl);
111 ahbh = gf64_mul(ah, bh);
112
113 ahbhB = ((ahbh & 0x1) << 5) |
114 ((ahbh & 0x20) >> 1) |
115 ((ahbh & 0x10) >> 1) | ((ahbh & 0x8) >> 1) | ((ahbh & 0x4) >> 1) | (((ahbh >> 1) ^ ahbh) & 0x1);
116
117 c = ((ablh ^ albl) << 6) | (ahbhB ^ albl);
118 return c;
119}
120
121static void find_2bit_err_pats(unsigned short s0, unsigned short s1, unsigned short r0, unsigned short r1, unsigned short *pats)
122{
123 find_2x2_soln(0x1, 0x1, r0, r1, s0, s1, pats);
124}
125
126static void find_3bit_err_coefs(unsigned short s0, unsigned short s1,
127 unsigned short s2, unsigned short s3, unsigned short s4, unsigned short s5, unsigned short *coefs)
128{
129 unsigned short m[3][4];
130 int row_order[3];
131
132 row_order[0] = 0;
133 row_order[1] = 1;
134 row_order[2] = 2;
135 m[0][0] = s2;
136 m[0][1] = s1;
137 m[0][2] = s0;
138 m[0][3] = s3;
139 m[1][0] = s3;
140 m[1][1] = s2;
141 m[1][2] = s1;
142 m[1][3] = s4;
143 m[2][0] = s4;
144 m[2][1] = s3;
145 m[2][2] = s2;
146 m[2][3] = s5;
147
148 if (m[0][2] != 0x0) {
149 zero_3x4_col2(m);
150 } else if (m[1][2] != 0x0) {
151 swap_3x4_rows(m, 0, 1, 4);
152 zero_3x4_col2(m);
153 } else if (m[2][2] != 0x0) {
154 swap_3x4_rows(m, 0, 2, 4);
155 zero_3x4_col2(m);
156 } else {
157 printk(KERN_ERR "Error: find_3bit_err_coefs, s0,s1,s2 all zeros!\n");
158 }
159
160 if (m[1][1] != 0x0) {
161 zero_3x4_col1(m);
162 } else if (m[2][1] != 0x0) {
163 swap_3x4_rows(m, 1, 2, 4);
164 zero_3x4_col1(m);
165 } else {
166 printk(KERN_ERR "Error: find_3bit_err_coefs, cannot resolve col 1!\n");
167 }
168
169 /* solve coefs */
170 solve_3x4(m, coefs, row_order);
171}
172
173static void zero_3x4_col2(unsigned short m[3][4])
174{
175 unsigned short minv1, minv2;
176
177 minv1 = gf4096_mul(m[1][2], gf4096_inv(m[0][2]));
178 minv2 = gf4096_mul(m[2][2], gf4096_inv(m[0][2]));
179 m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1);
180 m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1);
181 m[1][3] = m[1][3] ^ gf4096_mul(m[0][3], minv1);
182 m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2);
183 m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2);
184 m[2][3] = m[2][3] ^ gf4096_mul(m[0][3], minv2);
185}
186
187static void zero_3x4_col1(unsigned short m[3][4])
188{
189 unsigned short minv;
190 minv = gf4096_mul(m[2][1], gf4096_inv(m[1][1]));
191 m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv);
192 m[2][3] = m[2][3] ^ gf4096_mul(m[1][3], minv);
193}
194
195static void swap_3x4_rows(unsigned short m[3][4], int i, int j, int col_width)
196{
197 unsigned short tmp0;
198 int cnt;
199 for (cnt = 0; cnt < col_width; cnt++) {
200 tmp0 = m[i][cnt];
201 m[i][cnt] = m[j][cnt];
202 m[j][cnt] = tmp0;
203 }
204}
205
206static void solve_3x4(unsigned short m[3][4], unsigned short *coefs, int *row_order)
207{
208 unsigned short tmp[3];
209 tmp[0] = gf4096_mul(m[2][3], gf4096_inv(m[2][0]));
210 tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ m[1][3]), gf4096_inv(m[1][1]));
211 tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^ gf4096_mul(tmp[1], m[0][1]) ^ m[0][3]), gf4096_inv(m[0][2]));
212 sort_coefs(row_order, tmp, 3);
213 coefs[0] = tmp[0];
214 coefs[1] = tmp[1];
215 coefs[2] = tmp[2];
216}
217
218static void find_3bit_err_pats(unsigned short s0, unsigned short s1,
219 unsigned short s2, unsigned short r0,
220 unsigned short r1, unsigned short r2,
221 unsigned short *pats)
222{
223 find_2x2_soln(r0 ^ r2, r1 ^ r2,
224 gf4096_mul(r0, r0 ^ r2), gf4096_mul(r1, r1 ^ r2),
225 gf4096_mul(s0, r2) ^ s1, gf4096_mul(s1, r2) ^ s2, pats);
226 pats[2] = s0 ^ pats[0] ^ pats[1];
227}
228
229static void find_4bit_err_coefs(unsigned short s0, unsigned short s1,
230 unsigned short s2, unsigned short s3,
231 unsigned short s4, unsigned short s5,
232 unsigned short s6, unsigned short s7,
233 unsigned short *coefs)
234{
235 unsigned short m[4][5];
236 int row_order[4];
237
238 row_order[0] = 0;
239 row_order[1] = 1;
240 row_order[2] = 2;
241 row_order[3] = 3;
242
243 m[0][0] = s3;
244 m[0][1] = s2;
245 m[0][2] = s1;
246 m[0][3] = s0;
247 m[0][4] = s4;
248 m[1][0] = s4;
249 m[1][1] = s3;
250 m[1][2] = s2;
251 m[1][3] = s1;
252 m[1][4] = s5;
253 m[2][0] = s5;
254 m[2][1] = s4;
255 m[2][2] = s3;
256 m[2][3] = s2;
257 m[2][4] = s6;
258 m[3][0] = s6;
259 m[3][1] = s5;
260 m[3][2] = s4;
261 m[3][3] = s3;
262 m[3][4] = s7;
263
264 if (m[0][3] != 0x0) {
265 zero_4x5_col3(m);
266 } else if (m[1][3] != 0x0) {
267 swap_4x5_rows(m, 0, 1, 5);
268 zero_4x5_col3(m);
269 } else if (m[2][3] != 0x0) {
270 swap_4x5_rows(m, 0, 2, 5);
271 zero_4x5_col3(m);
272 } else if (m[3][3] != 0x0) {
273 swap_4x5_rows(m, 0, 3, 5);
274 zero_4x5_col3(m);
275 } else {
276 printk(KERN_ERR "Error: find_4bit_err_coefs, s0,s1,s2,s3 all zeros!\n");
277 }
278
279 if (m[1][2] != 0x0) {
280 zero_4x5_col2(m);
281 } else if (m[2][2] != 0x0) {
282 swap_4x5_rows(m, 1, 2, 5);
283 zero_4x5_col2(m);
284 } else if (m[3][2] != 0x0) {
285 swap_4x5_rows(m, 1, 3, 5);
286 zero_4x5_col2(m);
287 } else {
288 printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 2!\n");
289 }
290
291 if (m[2][1] != 0x0) {
292 zero_4x5_col1(m);
293 } else if (m[3][1] != 0x0) {
294 swap_4x5_rows(m, 2, 3, 5);
295 zero_4x5_col1(m);
296 } else {
297 printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 1!\n");
298 }
299
300 solve_4x5(m, coefs, row_order);
301}
302
303static void zero_4x5_col3(unsigned short m[4][5])
304{
305 unsigned short minv1, minv2, minv3;
306
307 minv1 = gf4096_mul(m[1][3], gf4096_inv(m[0][3]));
308 minv2 = gf4096_mul(m[2][3], gf4096_inv(m[0][3]));
309 minv3 = gf4096_mul(m[3][3], gf4096_inv(m[0][3]));
310
311 m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1);
312 m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1);
313 m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv1);
314 m[1][4] = m[1][4] ^ gf4096_mul(m[0][4], minv1);
315 m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2);
316 m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2);
317 m[2][2] = m[2][2] ^ gf4096_mul(m[0][2], minv2);
318 m[2][4] = m[2][4] ^ gf4096_mul(m[0][4], minv2);
319 m[3][0] = m[3][0] ^ gf4096_mul(m[0][0], minv3);
320 m[3][1] = m[3][1] ^ gf4096_mul(m[0][1], minv3);
321 m[3][2] = m[3][2] ^ gf4096_mul(m[0][2], minv3);
322 m[3][4] = m[3][4] ^ gf4096_mul(m[0][4], minv3);
323}
324
325static void zero_4x5_col2(unsigned short m[4][5])
326{
327 unsigned short minv2, minv3;
328
329 minv2 = gf4096_mul(m[2][2], gf4096_inv(m[1][2]));
330 minv3 = gf4096_mul(m[3][2], gf4096_inv(m[1][2]));
331
332 m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv2);
333 m[2][1] = m[2][1] ^ gf4096_mul(m[1][1], minv2);
334 m[2][4] = m[2][4] ^ gf4096_mul(m[1][4], minv2);
335 m[3][0] = m[3][0] ^ gf4096_mul(m[1][0], minv3);
336 m[3][1] = m[3][1] ^ gf4096_mul(m[1][1], minv3);
337 m[3][4] = m[3][4] ^ gf4096_mul(m[1][4], minv3);
338}
339
340static void zero_4x5_col1(unsigned short m[4][5])
341{
342 unsigned short minv;
343
344 minv = gf4096_mul(m[3][1], gf4096_inv(m[2][1]));
345
346 m[3][0] = m[3][0] ^ gf4096_mul(m[2][0], minv);
347 m[3][4] = m[3][4] ^ gf4096_mul(m[2][4], minv);
348}
349
350static void swap_4x5_rows(unsigned short m[4][5], int i, int j, int col_width)
351{
352 unsigned short tmp0;
353 int cnt;
354
355 for (cnt = 0; cnt < col_width; cnt++) {
356 tmp0 = m[i][cnt];
357 m[i][cnt] = m[j][cnt];
358 m[j][cnt] = tmp0;
359 }
360}
361
362static void solve_4x5(unsigned short m[4][5], unsigned short *coefs, int *row_order)
363{
364 unsigned short tmp[4];
365
366 tmp[0] = gf4096_mul(m[3][4], gf4096_inv(m[3][0]));
367 tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[2][0]) ^ m[2][4]), gf4096_inv(m[2][1]));
368 tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ gf4096_mul(tmp[1], m[1][1]) ^ m[1][4]), gf4096_inv(m[1][2]));
369 tmp[3] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^
370 gf4096_mul(tmp[1], m[0][1]) ^ gf4096_mul(tmp[2], m[0][2]) ^ m[0][4]), gf4096_inv(m[0][3]));
371 sort_coefs(row_order, tmp, 4);
372 coefs[0] = tmp[0];
373 coefs[1] = tmp[1];
374 coefs[2] = tmp[2];
375 coefs[3] = tmp[3];
376}
377
378static void sort_coefs(int *order, unsigned short *soln, int len)
379{
380 int cnt, start_cnt, least_ord, least_cnt;
381 unsigned short tmp0;
382 for (start_cnt = 0; start_cnt < len; start_cnt++) {
383 for (cnt = start_cnt; cnt < len; cnt++) {
384 if (cnt == start_cnt) {
385 least_ord = order[cnt];
386 least_cnt = start_cnt;
387 } else {
388 if (least_ord > order[cnt]) {
389 least_ord = order[cnt];
390 least_cnt = cnt;
391 }
392 }
393 }
394 if (least_cnt != start_cnt) {
395 tmp0 = order[least_cnt];
396 order[least_cnt] = order[start_cnt];
397 order[start_cnt] = tmp0;
398 tmp0 = soln[least_cnt];
399 soln[least_cnt] = soln[start_cnt];
400 soln[start_cnt] = tmp0;
401 }
402 }
403}
404
405static void find_4bit_err_pats(unsigned short s0, unsigned short s1,
406 unsigned short s2, unsigned short s3,
407 unsigned short z1, unsigned short z2,
408 unsigned short z3, unsigned short z4,
409 unsigned short *pats)
410{
411 unsigned short z4_z1, z3z4_z3z3, z4_z2, s0z4_s1, z1z4_z1z1,
412 z4_z3, z2z4_z2z2, s1z4_s2, z3z3z4_z3z3z3, z1z1z4_z1z1z1, z2z2z4_z2z2z2, s2z4_s3;
413 unsigned short tmp0, tmp1, tmp2, tmp3;
414
415 z4_z1 = z4 ^ z1;
416 z3z4_z3z3 = gf4096_mul(z3, z4) ^ gf4096_mul(z3, z3);
417 z4_z2 = z4 ^ z2;
418 s0z4_s1 = gf4096_mul(s0, z4) ^ s1;
419 z1z4_z1z1 = gf4096_mul(z1, z4) ^ gf4096_mul(z1, z1);
420 z4_z3 = z4 ^ z3;
421 z2z4_z2z2 = gf4096_mul(z2, z4) ^ gf4096_mul(z2, z2);
422 s1z4_s2 = gf4096_mul(s1, z4) ^ s2;
423 z3z3z4_z3z3z3 = gf4096_mul(gf4096_mul(z3, z3), z4) ^ gf4096_mul(gf4096_mul(z3, z3), z3);
424 z1z1z4_z1z1z1 = gf4096_mul(gf4096_mul(z1, z1), z4) ^ gf4096_mul(gf4096_mul(z1, z1), z1);
425 z2z2z4_z2z2z2 = gf4096_mul(gf4096_mul(z2, z2), z4) ^ gf4096_mul(gf4096_mul(z2, z2), z2);
426 s2z4_s3 = gf4096_mul(s2, z4) ^ s3;
427
428 //find err pat 0,1
429 find_2x2_soln(gf4096_mul(z4_z1, z3z4_z3z3) ^
430 gf4096_mul(z1z4_z1z1, z4_z3), gf4096_mul(z4_z2,
431 z3z4_z3z3) ^
432 gf4096_mul(z2z4_z2z2, z4_z3), gf4096_mul(z1z4_z1z1,
433 z3z3z4_z3z3z3) ^
434 gf4096_mul(z1z1z4_z1z1z1, z3z4_z3z3),
435 gf4096_mul(z2z4_z2z2,
436 z3z3z4_z3z3z3) ^ gf4096_mul(z2z2z4_z2z2z2,
437 z3z4_z3z3),
438 gf4096_mul(s0z4_s1, z3z4_z3z3) ^ gf4096_mul(s1z4_s2,
439 z4_z3),
440 gf4096_mul(s1z4_s2, z3z3z4_z3z3z3) ^ gf4096_mul(s2z4_s3, z3z4_z3z3), pats);
441 tmp0 = pats[0];
442 tmp1 = pats[1];
443 tmp2 = pats[0] ^ pats[1] ^ s0;
444 tmp3 = gf4096_mul(pats[0], z1) ^ gf4096_mul(pats[1], z2) ^ s1;
445
446 //find err pat 2,3
447 find_2x2_soln(0x1, 0x1, z3, z4, tmp2, tmp3, pats);
448 pats[2] = pats[0];
449 pats[3] = pats[1];
450 pats[0] = tmp0;
451 pats[1] = tmp1;
452}
453
454static void find_2x2_soln(unsigned short c00, unsigned short c01,
455 unsigned short c10, unsigned short c11,
456 unsigned short lval0, unsigned short lval1,
457 unsigned short *soln)
458{
459 unsigned short m[2][3];
460 m[0][0] = c00;
461 m[0][1] = c01;
462 m[0][2] = lval0;
463 m[1][0] = c10;
464 m[1][1] = c11;
465 m[1][2] = lval1;
466
467 if (m[0][1] != 0x0) {
468 /* */
469 } else if (m[1][1] != 0x0) {
470 swap_2x3_rows(m);
471 } else {
472 printk(KERN_ERR "Warning: find_2bit_err_coefs, s0,s1 all zeros!\n");
473 }
474
475 solve_2x3(m, soln);
476}
477
478static void swap_2x3_rows(unsigned short m[2][3])
479{
480 unsigned short tmp0;
481 int cnt;
482
483 for (cnt = 0; cnt < 3; cnt++) {
484 tmp0 = m[0][cnt];
485 m[0][cnt] = m[1][cnt];
486 m[1][cnt] = tmp0;
487 }
488}
489
490static void solve_2x3(unsigned short m[2][3], unsigned short *coefs)
491{
492 unsigned short minv;
493
494 minv = gf4096_mul(m[1][1], gf4096_inv(m[0][1]));
495 m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv);
496 m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv);
497 coefs[0] = gf4096_mul(m[1][2], gf4096_inv(m[1][0]));
498 coefs[1] = gf4096_mul((gf4096_mul(coefs[0], m[0][0]) ^ m[0][2]), gf4096_inv(m[0][1]));
499}
500
501static unsigned char gf64_inv[64] = {
David Woodhousefbad5692006-10-22 15:09:33 +0100502 0, 1, 33, 62, 49, 43, 31, 44, 57, 37, 52, 28, 46, 40, 22, 25,
David Woodhouse04459d72006-10-22 02:18:48 +0100503 61, 54, 51, 39, 26, 35, 14, 24, 23, 15, 20, 34, 11, 53, 45, 6,
504 63, 2, 27, 21, 56, 9, 50, 19, 13, 47, 48, 5, 7, 30, 12, 41,
David Woodhousefbad5692006-10-22 15:09:33 +0100505 42, 4, 38, 18, 10, 29, 17, 60, 36, 8, 59, 58, 55, 16, 3, 32
506};
David Woodhouse04459d72006-10-22 02:18:48 +0100507
508static unsigned short gf4096_inv(unsigned short din)
509{
510 unsigned short alahxal, ah2B, deno, inv, bl, bh;
511 unsigned short ah, al, ahxal;
512 unsigned short dout;
513
514 ah = (din >> 6) & 0x3f;
515 al = din & 0x3f;
516 ahxal = ah ^ al;
517 ah2B = (((ah ^ (ah >> 3)) & 0x1) << 5) |
518 ((ah >> 1) & 0x10) |
519 ((((ah >> 5) ^ (ah >> 2)) & 0x1) << 3) |
520 ((ah >> 2) & 0x4) | ((((ah >> 4) ^ (ah >> 1)) & 0x1) << 1) | (ah & 0x1);
521 alahxal = gf64_mul(ahxal, al);
522 deno = alahxal ^ ah2B;
523 inv = gf64_inv[deno];
524 bl = gf64_mul(inv, ahxal);
525 bh = gf64_mul(inv, ah);
526 dout = ((bh & 0x3f) << 6) | (bl & 0x3f);
527 return (((bh & 0x3f) << 6) | (bl & 0x3f));
528}
529
530static unsigned short err_pos_lut[4096] = {
531 0xfff, 0x000, 0x451, 0xfff, 0xfff, 0x3cf, 0xfff, 0x041,
532 0xfff, 0xfff, 0xfff, 0xfff, 0x28a, 0xfff, 0x492, 0xfff,
533 0x145, 0xfff, 0xfff, 0x514, 0xfff, 0x082, 0xfff, 0xfff,
534 0xfff, 0x249, 0x38e, 0x410, 0xfff, 0x104, 0x208, 0x1c7,
535 0xfff, 0xfff, 0xfff, 0xfff, 0x2cb, 0xfff, 0xfff, 0xfff,
536 0x0c3, 0x34d, 0x4d3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
537 0xfff, 0xfff, 0xfff, 0x186, 0xfff, 0xfff, 0xfff, 0xfff,
538 0xfff, 0x30c, 0x555, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
539 0xfff, 0xfff, 0xfff, 0x166, 0xfff, 0xfff, 0xfff, 0xfff,
540 0x385, 0x14e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e1,
541 0xfff, 0xfff, 0xfff, 0xfff, 0x538, 0xfff, 0x16d, 0xfff,
542 0xfff, 0xfff, 0x45b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
543 0xfff, 0xfff, 0xfff, 0x29c, 0x2cc, 0x30b, 0x2b3, 0xfff,
544 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0b3, 0xfff, 0x2f7,
545 0xfff, 0x32b, 0xfff, 0xfff, 0xfff, 0xfff, 0x0a7, 0xfff,
546 0xfff, 0x2da, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
547 0xfff, 0x07e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
548 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x11c, 0xfff, 0xfff,
549 0xfff, 0xfff, 0xfff, 0x22f, 0xfff, 0x1f4, 0xfff, 0xfff,
550 0x2b0, 0x504, 0xfff, 0x114, 0xfff, 0xfff, 0xfff, 0x21d,
551 0xfff, 0xfff, 0xfff, 0xfff, 0x00d, 0x3c4, 0x340, 0x10f,
552 0xfff, 0xfff, 0x266, 0x02e, 0xfff, 0xfff, 0xfff, 0x4f8,
553 0x337, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
554 0xfff, 0xfff, 0xfff, 0x07b, 0x168, 0xfff, 0xfff, 0x0fe,
555 0xfff, 0xfff, 0x51a, 0xfff, 0x458, 0xfff, 0x36d, 0xfff,
556 0xfff, 0xfff, 0xfff, 0x073, 0x37d, 0x415, 0x550, 0xfff,
557 0xfff, 0xfff, 0x23b, 0x4b4, 0xfff, 0xfff, 0xfff, 0x1a1,
558 0xfff, 0xfff, 0x3aa, 0xfff, 0x117, 0x04d, 0x341, 0xfff,
559 0xfff, 0xfff, 0xfff, 0x518, 0x03e, 0x0f2, 0xfff, 0xfff,
560 0xfff, 0xfff, 0xfff, 0x363, 0xfff, 0x0b9, 0xfff, 0xfff,
561 0x241, 0xfff, 0xfff, 0x049, 0xfff, 0xfff, 0xfff, 0xfff,
562 0x15f, 0x52d, 0xfff, 0xfff, 0xfff, 0x29e, 0xfff, 0xfff,
563 0xfff, 0xfff, 0x4cf, 0x0fc, 0xfff, 0x36f, 0x3d3, 0xfff,
564 0x228, 0xfff, 0xfff, 0x45e, 0xfff, 0xfff, 0xfff, 0xfff,
565 0x238, 0xfff, 0xfff, 0xfff, 0xfff, 0x47f, 0xfff, 0xfff,
566 0x43a, 0x265, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e8,
567 0xfff, 0xfff, 0x01a, 0xfff, 0xfff, 0xfff, 0xfff, 0x21e,
568 0x1fc, 0x40b, 0xfff, 0xfff, 0xfff, 0x2d0, 0x159, 0xfff,
569 0xfff, 0x313, 0xfff, 0xfff, 0x05c, 0x4cc, 0xfff, 0xfff,
570 0x0f6, 0x3d5, 0xfff, 0xfff, 0xfff, 0x54f, 0xfff, 0xfff,
571 0xfff, 0x172, 0x1e4, 0x07c, 0xfff, 0xfff, 0xfff, 0xfff,
572 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x53c, 0x1ad, 0x535,
573 0x19b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
574 0xfff, 0xfff, 0x092, 0xfff, 0x2be, 0xfff, 0xfff, 0x482,
575 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0e6, 0xfff, 0xfff,
576 0xfff, 0xfff, 0xfff, 0x476, 0xfff, 0x51d, 0xfff, 0xfff,
577 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
578 0xfff, 0xfff, 0x342, 0x2b5, 0x22e, 0x09a, 0xfff, 0x08d,
579 0x44f, 0x3ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d1, 0xfff,
580 0xfff, 0x543, 0xfff, 0x48f, 0xfff, 0x3d2, 0xfff, 0x0d5,
581 0x113, 0x0ec, 0x427, 0xfff, 0xfff, 0xfff, 0x4c4, 0xfff,
582 0xfff, 0x50a, 0xfff, 0x144, 0xfff, 0x105, 0x39f, 0x294,
583 0x164, 0xfff, 0x31a, 0xfff, 0xfff, 0x49a, 0xfff, 0x130,
584 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
585 0x1be, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
586 0xfff, 0xfff, 0x49e, 0x371, 0xfff, 0xfff, 0xfff, 0xfff,
587 0xfff, 0xfff, 0xfff, 0xfff, 0x0e8, 0x49c, 0x0f4, 0xfff,
588 0x338, 0x1a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
589 0xfff, 0x36c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
590 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
591 0xfff, 0x1ae, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
592 0xfff, 0x31b, 0xfff, 0xfff, 0x2dd, 0x522, 0xfff, 0xfff,
593 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f4,
594 0x3c6, 0x30d, 0xfff, 0xfff, 0xfff, 0xfff, 0x34c, 0x18f,
595 0x30a, 0xfff, 0x01f, 0x079, 0xfff, 0xfff, 0x54d, 0x46b,
596 0x28c, 0x37f, 0xfff, 0xfff, 0xfff, 0xfff, 0x355, 0xfff,
597 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x14f, 0xfff, 0xfff,
598 0xfff, 0xfff, 0xfff, 0x359, 0x3fe, 0x3c5, 0xfff, 0xfff,
599 0xfff, 0xfff, 0x423, 0xfff, 0xfff, 0x34a, 0x22c, 0xfff,
600 0x25a, 0xfff, 0xfff, 0x4ad, 0xfff, 0x28d, 0xfff, 0xfff,
601 0xfff, 0xfff, 0xfff, 0x547, 0xfff, 0xfff, 0xfff, 0xfff,
602 0x2e2, 0xfff, 0xfff, 0x1d5, 0xfff, 0x2a8, 0xfff, 0xfff,
603 0x03f, 0xfff, 0xfff, 0xfff, 0xfff, 0x3eb, 0x0fa, 0xfff,
604 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x55b, 0xfff,
605 0x08e, 0xfff, 0x3ae, 0xfff, 0x3a4, 0xfff, 0x282, 0x158,
606 0xfff, 0x382, 0xfff, 0xfff, 0x499, 0xfff, 0xfff, 0x08a,
607 0xfff, 0xfff, 0xfff, 0x456, 0x3be, 0xfff, 0x1e2, 0xfff,
608 0xfff, 0xfff, 0xfff, 0xfff, 0x559, 0xfff, 0x1a0, 0xfff,
609 0xfff, 0x0b4, 0xfff, 0xfff, 0xfff, 0x2df, 0xfff, 0xfff,
610 0xfff, 0x07f, 0x4f5, 0xfff, 0xfff, 0x27c, 0x133, 0x017,
611 0xfff, 0x3fd, 0xfff, 0xfff, 0xfff, 0x44d, 0x4cd, 0x17a,
612 0x0d7, 0x537, 0xfff, 0xfff, 0x353, 0xfff, 0xfff, 0x351,
613 0x366, 0xfff, 0x44a, 0xfff, 0x1a6, 0xfff, 0xfff, 0xfff,
614 0x291, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1e3,
615 0xfff, 0xfff, 0xfff, 0xfff, 0x389, 0xfff, 0x07a, 0xfff,
616 0x1b6, 0x2ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x24e, 0x074,
617 0xfff, 0xfff, 0x3dc, 0xfff, 0x4e3, 0xfff, 0xfff, 0xfff,
618 0xfff, 0x4eb, 0xfff, 0xfff, 0x3b8, 0x4de, 0xfff, 0x19c,
619 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x262,
620 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x076, 0x4e8, 0x3da,
621 0xfff, 0x531, 0xfff, 0xfff, 0x14a, 0xfff, 0x0a2, 0x433,
622 0x3df, 0x1e9, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e7, 0x285,
623 0x2d8, 0xfff, 0xfff, 0xfff, 0x349, 0x18d, 0x098, 0xfff,
624 0x0df, 0x4bf, 0xfff, 0xfff, 0x0b2, 0xfff, 0x346, 0x24d,
625 0xfff, 0xfff, 0xfff, 0x24f, 0x4fa, 0x2f9, 0xfff, 0xfff,
626 0x3c9, 0xfff, 0x2b4, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
627 0xfff, 0x056, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
628 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
629 0xfff, 0x179, 0xfff, 0x0e9, 0x3f0, 0x33d, 0xfff, 0xfff,
630 0xfff, 0xfff, 0xfff, 0x1fd, 0xfff, 0xfff, 0x526, 0xfff,
631 0xfff, 0xfff, 0x53d, 0xfff, 0xfff, 0xfff, 0x170, 0x331,
632 0xfff, 0x068, 0xfff, 0xfff, 0xfff, 0x3f7, 0xfff, 0x3d8,
633 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
634 0xfff, 0x09f, 0x556, 0xfff, 0xfff, 0x02d, 0xfff, 0xfff,
635 0x553, 0xfff, 0xfff, 0xfff, 0x1f0, 0xfff, 0xfff, 0x4d6,
636 0x41e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d5, 0xfff, 0xfff,
637 0xfff, 0xfff, 0xfff, 0x248, 0xfff, 0xfff, 0xfff, 0x0a3,
638 0xfff, 0x217, 0xfff, 0xfff, 0xfff, 0x4f1, 0x209, 0xfff,
639 0xfff, 0x475, 0x234, 0x52b, 0x398, 0xfff, 0x08b, 0xfff,
640 0xfff, 0xfff, 0xfff, 0x2c2, 0xfff, 0xfff, 0xfff, 0xfff,
641 0xfff, 0xfff, 0x268, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
642 0xfff, 0x4a3, 0xfff, 0x0aa, 0xfff, 0x1d9, 0xfff, 0xfff,
643 0xfff, 0xfff, 0x155, 0xfff, 0xfff, 0xfff, 0xfff, 0x0bf,
644 0x539, 0xfff, 0xfff, 0x2f1, 0x545, 0xfff, 0xfff, 0xfff,
645 0xfff, 0xfff, 0xfff, 0x2a7, 0x06f, 0xfff, 0x378, 0xfff,
646 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x25e, 0xfff,
647 0xfff, 0xfff, 0xfff, 0x15d, 0x02a, 0xfff, 0xfff, 0x0bc,
648 0x235, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
649 0x150, 0xfff, 0x1a9, 0xfff, 0xfff, 0xfff, 0xfff, 0x381,
650 0xfff, 0x04e, 0x270, 0x13f, 0xfff, 0xfff, 0x405, 0xfff,
651 0x3cd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
652 0xfff, 0x2ef, 0xfff, 0x06a, 0xfff, 0xfff, 0xfff, 0x34f,
653 0x212, 0xfff, 0xfff, 0x0e2, 0xfff, 0x083, 0x298, 0xfff,
654 0xfff, 0xfff, 0x0c2, 0xfff, 0xfff, 0x52e, 0xfff, 0x488,
655 0xfff, 0xfff, 0xfff, 0x36b, 0xfff, 0xfff, 0xfff, 0x442,
656 0x091, 0xfff, 0x41c, 0xfff, 0xfff, 0x3a5, 0xfff, 0x4e6,
657 0xfff, 0xfff, 0x40d, 0x31d, 0xfff, 0xfff, 0xfff, 0x4c1,
658 0x053, 0xfff, 0x418, 0x13c, 0xfff, 0x350, 0xfff, 0x0ae,
659 0xfff, 0xfff, 0x41f, 0xfff, 0x470, 0xfff, 0x4ca, 0xfff,
660 0xfff, 0xfff, 0x02b, 0x450, 0xfff, 0x1f8, 0xfff, 0xfff,
661 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x293, 0xfff,
662 0xfff, 0xfff, 0xfff, 0x411, 0xfff, 0xfff, 0xfff, 0xfff,
663 0xfff, 0xfff, 0xfff, 0xfff, 0x0b8, 0xfff, 0xfff, 0xfff,
664 0x3e1, 0xfff, 0xfff, 0xfff, 0xfff, 0x43c, 0xfff, 0x2b2,
665 0x2ab, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ec,
666 0xfff, 0xfff, 0xfff, 0x3f8, 0x034, 0xfff, 0xfff, 0xfff,
667 0xfff, 0xfff, 0xfff, 0x11a, 0xfff, 0x541, 0x45c, 0x134,
668 0x1cc, 0xfff, 0xfff, 0xfff, 0x469, 0xfff, 0xfff, 0x44b,
669 0x161, 0xfff, 0xfff, 0xfff, 0x055, 0xfff, 0xfff, 0xfff,
670 0xfff, 0x307, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d1, 0xfff,
671 0xfff, 0xfff, 0x124, 0x37b, 0x26b, 0x336, 0xfff, 0xfff,
672 0x2e4, 0x3cb, 0xfff, 0xfff, 0x0f8, 0x3c8, 0xfff, 0xfff,
673 0xfff, 0x461, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4b5,
674 0x2cf, 0xfff, 0xfff, 0xfff, 0x20f, 0xfff, 0x35a, 0xfff,
675 0x490, 0xfff, 0x185, 0xfff, 0xfff, 0xfff, 0xfff, 0x42e,
676 0xfff, 0xfff, 0xfff, 0xfff, 0x54b, 0xfff, 0xfff, 0xfff,
677 0x146, 0xfff, 0x412, 0xfff, 0xfff, 0xfff, 0x1ff, 0xfff,
678 0xfff, 0x3e0, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d5, 0xfff,
679 0x4df, 0x505, 0xfff, 0x413, 0xfff, 0x1a5, 0xfff, 0x3b2,
680 0xfff, 0xfff, 0xfff, 0x35b, 0xfff, 0x116, 0xfff, 0xfff,
681 0x171, 0x4d0, 0xfff, 0x154, 0x12d, 0xfff, 0xfff, 0xfff,
682 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x468, 0x4db, 0xfff,
683 0xfff, 0x1df, 0xfff, 0xfff, 0xfff, 0xfff, 0x05a, 0xfff,
684 0x0f1, 0x403, 0xfff, 0x22b, 0x2e0, 0xfff, 0xfff, 0xfff,
685 0x2b7, 0x373, 0xfff, 0xfff, 0xfff, 0xfff, 0x13e, 0xfff,
686 0xfff, 0xfff, 0x0d0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
687 0x329, 0x1d2, 0x3fa, 0x047, 0xfff, 0x2f2, 0xfff, 0xfff,
688 0x141, 0x0ac, 0x1d7, 0xfff, 0x07d, 0xfff, 0xfff, 0xfff,
689 0x1c1, 0xfff, 0x487, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
690 0xfff, 0xfff, 0xfff, 0x045, 0xfff, 0xfff, 0xfff, 0xfff,
691 0x288, 0x0cd, 0xfff, 0xfff, 0xfff, 0xfff, 0x226, 0x1d8,
692 0xfff, 0x153, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4cb,
693 0x528, 0xfff, 0xfff, 0xfff, 0x20a, 0x343, 0x3a1, 0xfff,
694 0xfff, 0xfff, 0x2d7, 0x2d3, 0x1aa, 0x4c5, 0xfff, 0xfff,
695 0xfff, 0x42b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
696 0xfff, 0xfff, 0xfff, 0xfff, 0x3e9, 0xfff, 0x20b, 0x260,
697 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x37c, 0x2fd,
698 0xfff, 0xfff, 0x2c8, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
699 0xfff, 0x31e, 0xfff, 0x335, 0xfff, 0xfff, 0xfff, 0xfff,
700 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
701 0xfff, 0xfff, 0x135, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
702 0xfff, 0xfff, 0x35c, 0x4dd, 0x129, 0xfff, 0xfff, 0xfff,
703 0xfff, 0xfff, 0x1ef, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
704 0xfff, 0x34e, 0xfff, 0xfff, 0xfff, 0xfff, 0x407, 0xfff,
705 0xfff, 0xfff, 0xfff, 0xfff, 0x3ad, 0xfff, 0xfff, 0xfff,
706 0x379, 0xfff, 0xfff, 0x1d0, 0x38d, 0xfff, 0xfff, 0x1e8,
707 0x184, 0x3c1, 0x1c4, 0xfff, 0x1f9, 0xfff, 0xfff, 0x424,
708 0xfff, 0xfff, 0xfff, 0xfff, 0x1d3, 0x0d4, 0xfff, 0x4e9,
709 0xfff, 0xfff, 0xfff, 0x530, 0x107, 0xfff, 0x106, 0x04f,
710 0xfff, 0xfff, 0x4c7, 0x503, 0xfff, 0xfff, 0xfff, 0xfff,
711 0xfff, 0x15c, 0xfff, 0x23f, 0xfff, 0xfff, 0xfff, 0xfff,
712 0xfff, 0xfff, 0xfff, 0xfff, 0x4f3, 0xfff, 0xfff, 0x3c7,
713 0xfff, 0x278, 0xfff, 0xfff, 0x0a6, 0xfff, 0xfff, 0xfff,
714 0x122, 0x1cf, 0xfff, 0x327, 0xfff, 0x2e5, 0xfff, 0x29d,
715 0xfff, 0xfff, 0x3f1, 0xfff, 0xfff, 0x48d, 0xfff, 0xfff,
716 0xfff, 0xfff, 0x054, 0xfff, 0xfff, 0xfff, 0xfff, 0x178,
717 0x27e, 0x4e0, 0x352, 0x02f, 0x09c, 0xfff, 0x2a0, 0xfff,
718 0xfff, 0x46a, 0x457, 0xfff, 0xfff, 0x501, 0xfff, 0x2ba,
719 0xfff, 0xfff, 0xfff, 0x54e, 0x2e7, 0xfff, 0xfff, 0xfff,
720 0xfff, 0xfff, 0x551, 0xfff, 0xfff, 0x1db, 0x2aa, 0xfff,
721 0xfff, 0x4bc, 0xfff, 0xfff, 0x395, 0xfff, 0x0de, 0xfff,
722 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x455, 0xfff, 0x17e,
723 0xfff, 0x221, 0x4a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
724 0x388, 0xfff, 0xfff, 0xfff, 0x308, 0xfff, 0xfff, 0xfff,
725 0x20e, 0x4b9, 0xfff, 0x273, 0x20c, 0x09e, 0xfff, 0x057,
726 0xfff, 0xfff, 0xfff, 0xfff, 0x3f2, 0xfff, 0x1a8, 0x3a6,
727 0x14c, 0xfff, 0xfff, 0x071, 0xfff, 0xfff, 0x53a, 0xfff,
728 0xfff, 0xfff, 0xfff, 0x109, 0xfff, 0xfff, 0x399, 0xfff,
729 0x061, 0x4f0, 0x39e, 0x244, 0xfff, 0x035, 0xfff, 0xfff,
730 0x305, 0x47e, 0x297, 0xfff, 0xfff, 0x2b8, 0xfff, 0xfff,
731 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1bc, 0xfff, 0x2fc,
732 0xfff, 0xfff, 0x554, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b6,
733 0xfff, 0xfff, 0xfff, 0x515, 0x397, 0xfff, 0xfff, 0x12f,
734 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e5,
735 0xfff, 0x4fc, 0xfff, 0xfff, 0x05e, 0xfff, 0xfff, 0xfff,
736 0xfff, 0xfff, 0x0a8, 0x3af, 0x015, 0xfff, 0xfff, 0xfff,
737 0xfff, 0x138, 0xfff, 0xfff, 0xfff, 0x540, 0xfff, 0xfff,
738 0xfff, 0x027, 0x523, 0x2f0, 0xfff, 0xfff, 0xfff, 0xfff,
739 0xfff, 0xfff, 0x16c, 0xfff, 0x27d, 0xfff, 0xfff, 0xfff,
740 0xfff, 0x04c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4dc,
741 0xfff, 0xfff, 0x059, 0x301, 0xfff, 0xfff, 0xfff, 0xfff,
742 0xfff, 0xfff, 0xfff, 0x1a3, 0xfff, 0x15a, 0xfff, 0xfff,
743 0x0a5, 0xfff, 0x435, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
744 0xfff, 0x051, 0xfff, 0xfff, 0x131, 0xfff, 0x4f4, 0xfff,
745 0xfff, 0xfff, 0xfff, 0x441, 0xfff, 0x4fb, 0xfff, 0x03b,
746 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ed, 0x274,
747 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d3, 0x55e, 0x1b3,
748 0xfff, 0x0bd, 0xfff, 0xfff, 0xfff, 0xfff, 0x225, 0xfff,
749 0xfff, 0xfff, 0xfff, 0xfff, 0x4b7, 0xfff, 0xfff, 0x2ff,
750 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c3, 0xfff,
751 0x383, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f6,
752 0xfff, 0xfff, 0x1ee, 0xfff, 0x03d, 0xfff, 0xfff, 0xfff,
753 0xfff, 0xfff, 0x26f, 0x1dc, 0xfff, 0x0db, 0xfff, 0xfff,
754 0xfff, 0xfff, 0xfff, 0x0ce, 0xfff, 0xfff, 0x127, 0x03a,
755 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x311, 0xfff,
756 0xfff, 0x13d, 0x09d, 0x47b, 0x2a6, 0x50d, 0x510, 0x19a,
757 0xfff, 0x354, 0x414, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
758 0xfff, 0xfff, 0x44c, 0x3b0, 0xfff, 0x23d, 0x429, 0xfff,
759 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
760 0x4c0, 0x416, 0xfff, 0x05b, 0xfff, 0xfff, 0x137, 0xfff,
761 0x25f, 0x49f, 0xfff, 0x279, 0x013, 0xfff, 0xfff, 0xfff,
762 0x269, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
763 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d0, 0xfff, 0xfff,
764 0xfff, 0xfff, 0xfff, 0xfff, 0x077, 0xfff, 0xfff, 0x3fb,
765 0xfff, 0xfff, 0xfff, 0xfff, 0x271, 0x3a0, 0xfff, 0xfff,
766 0x40f, 0xfff, 0xfff, 0x3de, 0xfff, 0xfff, 0xfff, 0xfff,
767 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ab, 0x26a,
768 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x489, 0xfff, 0xfff,
769 0x252, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b7, 0x42f, 0xfff,
770 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b7,
771 0xfff, 0x2bb, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
772 0xfff, 0xfff, 0xfff, 0x0f7, 0x01d, 0xfff, 0x067, 0xfff,
773 0xfff, 0xfff, 0xfff, 0x4e2, 0xfff, 0xfff, 0x4bb, 0xfff,
774 0xfff, 0xfff, 0x17b, 0xfff, 0x0ee, 0xfff, 0xfff, 0xfff,
775 0xfff, 0xfff, 0x36e, 0xfff, 0xfff, 0xfff, 0x533, 0xfff,
776 0xfff, 0xfff, 0x4d4, 0x356, 0xfff, 0xfff, 0x375, 0xfff,
777 0xfff, 0xfff, 0xfff, 0x4a4, 0x513, 0xfff, 0xfff, 0xfff,
778 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4ff, 0xfff, 0x2af,
779 0xfff, 0xfff, 0x026, 0xfff, 0x0ad, 0xfff, 0xfff, 0xfff,
780 0xfff, 0x26e, 0xfff, 0xfff, 0xfff, 0xfff, 0x493, 0xfff,
781 0x463, 0x4d2, 0x4be, 0xfff, 0xfff, 0xfff, 0xfff, 0x4f2,
782 0x0b6, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
783 0xfff, 0x32d, 0x315, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
784 0xfff, 0x13a, 0x4a1, 0xfff, 0x27a, 0xfff, 0xfff, 0xfff,
785 0x47a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
786 0x334, 0xfff, 0xfff, 0xfff, 0xfff, 0x54c, 0xfff, 0xfff,
787 0xfff, 0x0c9, 0x007, 0xfff, 0xfff, 0x12e, 0xfff, 0x0ff,
788 0xfff, 0xfff, 0x3f5, 0x509, 0xfff, 0xfff, 0xfff, 0xfff,
789 0x1c3, 0x2ad, 0xfff, 0xfff, 0x47c, 0x261, 0xfff, 0xfff,
790 0xfff, 0xfff, 0xfff, 0x152, 0xfff, 0xfff, 0xfff, 0x339,
791 0xfff, 0x243, 0x1c0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
792 0x063, 0xfff, 0xfff, 0x254, 0xfff, 0xfff, 0x173, 0xfff,
793 0x0c7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
794 0xfff, 0x362, 0x259, 0x485, 0x374, 0x0dc, 0x3ab, 0xfff,
795 0x1c5, 0x534, 0x544, 0xfff, 0xfff, 0x508, 0xfff, 0x402,
796 0x408, 0xfff, 0x0e7, 0xfff, 0xfff, 0x00a, 0x205, 0xfff,
797 0xfff, 0x2b9, 0xfff, 0xfff, 0xfff, 0x465, 0xfff, 0xfff,
798 0xfff, 0xfff, 0xfff, 0xfff, 0x23a, 0xfff, 0xfff, 0xfff,
799 0xfff, 0x147, 0x19d, 0x115, 0x214, 0xfff, 0x090, 0x368,
800 0xfff, 0x210, 0xfff, 0xfff, 0x280, 0x52a, 0x163, 0x148,
801 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x326, 0xfff, 0xfff,
802 0xfff, 0xfff, 0xfff, 0x2de, 0xfff, 0xfff, 0xfff, 0xfff,
803 0x206, 0x2c1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
804 0x189, 0xfff, 0xfff, 0xfff, 0xfff, 0x367, 0xfff, 0x1a4,
805 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x443, 0xfff, 0x27b,
806 0xfff, 0xfff, 0x251, 0x549, 0xfff, 0xfff, 0xfff, 0xfff,
807 0xfff, 0xfff, 0x188, 0x04b, 0xfff, 0xfff, 0xfff, 0x31f,
808 0x4a6, 0xfff, 0x246, 0x1de, 0x156, 0xfff, 0xfff, 0xfff,
809 0x3a9, 0xfff, 0xfff, 0xfff, 0x2fa, 0xfff, 0x128, 0x0d1,
810 0x449, 0x255, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
811 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
812 0xfff, 0xfff, 0xfff, 0xfff, 0x258, 0xfff, 0xfff, 0xfff,
813 0x532, 0xfff, 0xfff, 0xfff, 0x303, 0x517, 0xfff, 0xfff,
814 0x2a9, 0x24a, 0xfff, 0xfff, 0x231, 0xfff, 0xfff, 0xfff,
815 0xfff, 0xfff, 0x4b6, 0x516, 0xfff, 0xfff, 0x0e4, 0x0eb,
816 0xfff, 0x4e4, 0xfff, 0x275, 0xfff, 0xfff, 0x031, 0xfff,
817 0xfff, 0xfff, 0xfff, 0xfff, 0x025, 0x21a, 0xfff, 0x0cc,
818 0x45f, 0x3d9, 0x289, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
819 0xfff, 0xfff, 0x23e, 0xfff, 0xfff, 0xfff, 0x438, 0x097,
820 0x419, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
821 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
822 0xfff, 0xfff, 0x0a9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
823 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
824 0x37e, 0x0e0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x431,
825 0x372, 0xfff, 0xfff, 0xfff, 0x1ba, 0x06e, 0xfff, 0x1b1,
826 0xfff, 0xfff, 0x12a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
827 0xfff, 0xfff, 0x193, 0xfff, 0xfff, 0xfff, 0xfff, 0x10a,
828 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x048, 0x1b4,
829 0xfff, 0xfff, 0xfff, 0xfff, 0x295, 0x140, 0x108, 0xfff,
830 0xfff, 0xfff, 0xfff, 0x16f, 0xfff, 0x0a4, 0x37a, 0xfff,
831 0x29a, 0xfff, 0x284, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c6,
832 0x2a2, 0x3a3, 0xfff, 0x201, 0xfff, 0xfff, 0xfff, 0x4bd,
833 0x005, 0x54a, 0x3b5, 0x204, 0x2ee, 0x11d, 0x436, 0xfff,
834 0xfff, 0xfff, 0xfff, 0xfff, 0x3ec, 0xfff, 0xfff, 0xfff,
835 0xfff, 0xfff, 0xfff, 0xfff, 0x11f, 0x498, 0x21c, 0xfff,
836 0xfff, 0xfff, 0x3d6, 0xfff, 0x4ab, 0xfff, 0x432, 0x2eb,
837 0x542, 0x4fd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
838 0xfff, 0xfff, 0xfff, 0x4ce, 0xfff, 0xfff, 0x2fb, 0xfff,
839 0xfff, 0x2e1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
840 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b9, 0x037, 0x0dd,
841 0xfff, 0xfff, 0xfff, 0x2bf, 0x521, 0x496, 0x095, 0xfff,
842 0xfff, 0x328, 0x070, 0x1bf, 0xfff, 0x393, 0xfff, 0xfff,
843 0x102, 0xfff, 0xfff, 0x21b, 0xfff, 0x142, 0x263, 0x519,
844 0xfff, 0x2a5, 0x177, 0xfff, 0x14d, 0x471, 0x4ae, 0xfff,
845 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
846 0x1f6, 0xfff, 0x481, 0xfff, 0xfff, 0xfff, 0x151, 0xfff,
847 0xfff, 0xfff, 0x085, 0x33f, 0xfff, 0xfff, 0xfff, 0x084,
848 0xfff, 0xfff, 0xfff, 0x345, 0x3a2, 0xfff, 0xfff, 0x0a0,
849 0x0da, 0x024, 0xfff, 0xfff, 0xfff, 0x1bd, 0xfff, 0x55c,
850 0x467, 0x445, 0xfff, 0xfff, 0xfff, 0x052, 0xfff, 0xfff,
851 0xfff, 0xfff, 0x51e, 0xfff, 0xfff, 0x39d, 0xfff, 0x35f,
852 0xfff, 0x376, 0x3ee, 0xfff, 0xfff, 0xfff, 0xfff, 0x448,
853 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x16a,
854 0xfff, 0x036, 0x38f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
855 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x211,
856 0xfff, 0xfff, 0xfff, 0x230, 0xfff, 0xfff, 0x3ba, 0xfff,
857 0xfff, 0xfff, 0x3ce, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
858 0xfff, 0xfff, 0xfff, 0x229, 0xfff, 0x176, 0xfff, 0xfff,
859 0xfff, 0xfff, 0xfff, 0x00b, 0xfff, 0x162, 0x018, 0xfff,
860 0xfff, 0x233, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
861 0x400, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
862 0xfff, 0xfff, 0xfff, 0x12b, 0xfff, 0xfff, 0xfff, 0xfff,
863 0xfff, 0x3f4, 0xfff, 0x0f0, 0xfff, 0x1ac, 0xfff, 0xfff,
864 0x119, 0xfff, 0x2c0, 0xfff, 0xfff, 0xfff, 0x49b, 0xfff,
865 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x23c, 0xfff,
866 0x4b3, 0x010, 0x064, 0xfff, 0xfff, 0x4ba, 0xfff, 0xfff,
867 0xfff, 0xfff, 0xfff, 0x3c2, 0xfff, 0xfff, 0xfff, 0xfff,
868 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x006, 0x196, 0xfff,
869 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x100, 0x191, 0xfff,
870 0x1ea, 0x29f, 0xfff, 0xfff, 0xfff, 0x276, 0xfff, 0xfff,
871 0x2b1, 0x3b9, 0xfff, 0x03c, 0xfff, 0xfff, 0xfff, 0x180,
872 0xfff, 0x08f, 0xfff, 0xfff, 0x19e, 0x019, 0xfff, 0x0b0,
873 0x0fd, 0x332, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
874 0xfff, 0x06b, 0x2e8, 0xfff, 0x446, 0xfff, 0xfff, 0x004,
875 0x247, 0x197, 0xfff, 0x112, 0x169, 0x292, 0xfff, 0x302,
876 0xfff, 0xfff, 0x33b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
877 0xfff, 0xfff, 0xfff, 0x287, 0x21f, 0xfff, 0x3ea, 0xfff,
878 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e7, 0xfff, 0xfff,
879 0xfff, 0xfff, 0xfff, 0x3a8, 0xfff, 0xfff, 0x2bc, 0xfff,
880 0x484, 0x296, 0xfff, 0x1c9, 0x08c, 0x1e5, 0x48a, 0xfff,
881 0x360, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
882 0x1ca, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
883 0xfff, 0xfff, 0xfff, 0x10d, 0xfff, 0xfff, 0xfff, 0xfff,
884 0xfff, 0xfff, 0x066, 0x2ea, 0x28b, 0x25b, 0xfff, 0x072,
885 0xfff, 0xfff, 0xfff, 0xfff, 0x2b6, 0xfff, 0xfff, 0x272,
886 0xfff, 0xfff, 0x525, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
887 0x2ca, 0xfff, 0xfff, 0xfff, 0x299, 0xfff, 0xfff, 0xfff,
888 0x558, 0x41a, 0xfff, 0x4f7, 0x557, 0xfff, 0x4a0, 0x344,
889 0x12c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x125,
890 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
891 0x40e, 0xfff, 0xfff, 0x502, 0xfff, 0x103, 0x3e6, 0xfff,
892 0x527, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
893 0xfff, 0xfff, 0xfff, 0x45d, 0xfff, 0xfff, 0xfff, 0xfff,
894 0x44e, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d2, 0x4c9, 0x35e,
895 0x459, 0x2d9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x17d,
896 0x0c4, 0xfff, 0xfff, 0xfff, 0x3ac, 0x390, 0x094, 0xfff,
897 0x483, 0x0ab, 0xfff, 0x253, 0xfff, 0x391, 0xfff, 0xfff,
898 0xfff, 0xfff, 0x123, 0x0ef, 0xfff, 0xfff, 0xfff, 0x330,
899 0x38c, 0xfff, 0xfff, 0x2ae, 0xfff, 0xfff, 0xfff, 0x042,
900 0x012, 0x06d, 0xfff, 0xfff, 0xfff, 0x32a, 0x3db, 0x364,
901 0x2dc, 0xfff, 0x30f, 0x3d7, 0x4a5, 0x050, 0xfff, 0xfff,
902 0x029, 0xfff, 0xfff, 0xfff, 0xfff, 0x1d1, 0xfff, 0xfff,
903 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x480, 0xfff,
904 0x4ed, 0x081, 0x0a1, 0xfff, 0xfff, 0xfff, 0x30e, 0x52f,
905 0x257, 0xfff, 0xfff, 0x447, 0xfff, 0xfff, 0xfff, 0xfff,
906 0xfff, 0xfff, 0xfff, 0x401, 0x3cc, 0xfff, 0xfff, 0x0fb,
907 0x2c9, 0x42a, 0x314, 0x33e, 0x3bd, 0x318, 0xfff, 0x10e,
908 0x2a1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x24c,
909 0x506, 0xfff, 0x267, 0xfff, 0xfff, 0x219, 0xfff, 0x1eb,
910 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
911 0x309, 0x3e2, 0x46c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
912 0x384, 0xfff, 0xfff, 0xfff, 0xfff, 0x50c, 0xfff, 0x24b,
913 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x038,
914 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x194,
915 0x143, 0x3e3, 0xfff, 0xfff, 0xfff, 0x4c2, 0xfff, 0xfff,
916 0x0e1, 0x25c, 0xfff, 0x237, 0xfff, 0x1fe, 0xfff, 0xfff,
917 0xfff, 0x065, 0x2a4, 0xfff, 0x386, 0x55a, 0x11b, 0xfff,
918 0xfff, 0x192, 0xfff, 0x183, 0x00e, 0xfff, 0xfff, 0xfff,
919 0xfff, 0xfff, 0xfff, 0x4b2, 0x18e, 0xfff, 0xfff, 0xfff,
920 0xfff, 0x486, 0x4ef, 0x0c6, 0x380, 0xfff, 0x4a8, 0xfff,
921 0x0c5, 0xfff, 0xfff, 0xfff, 0xfff, 0x093, 0x1b8, 0xfff,
922 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e6,
923 0xfff, 0x0f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
924 0x28e, 0xfff, 0x53b, 0x420, 0x22a, 0x33a, 0xfff, 0x387,
925 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2a3, 0xfff, 0xfff,
926 0xfff, 0x428, 0x500, 0xfff, 0xfff, 0x120, 0x2c6, 0x290,
927 0x2f5, 0x0e3, 0xfff, 0x0b7, 0xfff, 0x319, 0x474, 0xfff,
928 0xfff, 0xfff, 0x529, 0x014, 0xfff, 0x41b, 0x40a, 0x18b,
929 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d9,
930 0xfff, 0x38a, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ce, 0xfff,
931 0xfff, 0xfff, 0xfff, 0xfff, 0x3b1, 0xfff, 0xfff, 0x05d,
932 0x2c4, 0xfff, 0xfff, 0x4af, 0xfff, 0x030, 0xfff, 0xfff,
933 0x203, 0xfff, 0x277, 0x256, 0xfff, 0xfff, 0xfff, 0x4f9,
934 0xfff, 0x2c7, 0xfff, 0x466, 0x016, 0x1cd, 0xfff, 0x167,
935 0xfff, 0xfff, 0x0c8, 0xfff, 0x43d, 0xfff, 0xfff, 0x020,
936 0xfff, 0xfff, 0x232, 0x1cb, 0x1e0, 0xfff, 0xfff, 0x347,
937 0xfff, 0x478, 0xfff, 0x365, 0xfff, 0xfff, 0xfff, 0xfff,
938 0x358, 0xfff, 0x10b, 0xfff, 0x35d, 0xfff, 0xfff, 0xfff,
939 0xfff, 0xfff, 0x452, 0x22d, 0xfff, 0xfff, 0x47d, 0xfff,
940 0x2f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x460, 0xfff,
941 0xfff, 0xfff, 0x50b, 0xfff, 0xfff, 0xfff, 0x2ec, 0xfff,
942 0xfff, 0xfff, 0xfff, 0xfff, 0x4b1, 0x422, 0xfff, 0xfff,
943 0xfff, 0x2d4, 0xfff, 0x239, 0xfff, 0xfff, 0xfff, 0x439,
944 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
945 0xfff, 0x491, 0x075, 0xfff, 0xfff, 0xfff, 0x06c, 0xfff,
946 0xfff, 0x0f9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
947 0xfff, 0x139, 0xfff, 0x4f6, 0xfff, 0xfff, 0x409, 0xfff,
948 0xfff, 0x15b, 0xfff, 0xfff, 0x348, 0xfff, 0xfff, 0xfff,
949 0xfff, 0x4a2, 0x49d, 0xfff, 0x033, 0x175, 0xfff, 0x039,
950 0xfff, 0x312, 0x40c, 0xfff, 0xfff, 0x325, 0xfff, 0xfff,
951 0xfff, 0xfff, 0xfff, 0xfff, 0x4aa, 0xfff, 0xfff, 0xfff,
952 0xfff, 0xfff, 0xfff, 0x165, 0x3bc, 0x48c, 0x310, 0x096,
953 0xfff, 0xfff, 0x250, 0x1a2, 0xfff, 0xfff, 0xfff, 0xfff,
954 0x20d, 0x2ac, 0xfff, 0xfff, 0x39b, 0xfff, 0x377, 0xfff,
955 0x512, 0x495, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
956 0xfff, 0xfff, 0xfff, 0xfff, 0x357, 0x4ea, 0xfff, 0xfff,
957 0xfff, 0xfff, 0x198, 0xfff, 0xfff, 0xfff, 0x434, 0x04a,
958 0xfff, 0xfff, 0xfff, 0xfff, 0x062, 0xfff, 0x1d6, 0x1c8,
959 0xfff, 0x1f3, 0x281, 0xfff, 0x462, 0xfff, 0xfff, 0xfff,
960 0x4b0, 0xfff, 0x207, 0xfff, 0xfff, 0xfff, 0xfff, 0x3dd,
961 0xfff, 0xfff, 0x55d, 0xfff, 0x552, 0x494, 0x1af, 0xfff,
962 0xfff, 0xfff, 0xfff, 0xfff, 0x227, 0xfff, 0xfff, 0x069,
963 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x43e,
964 0x0b5, 0xfff, 0x524, 0x2d2, 0xfff, 0xfff, 0xfff, 0x28f,
965 0xfff, 0x01b, 0x50e, 0xfff, 0xfff, 0x1bb, 0xfff, 0xfff,
966 0x41d, 0xfff, 0x32e, 0x48e, 0xfff, 0x1f7, 0x224, 0xfff,
967 0xfff, 0xfff, 0xfff, 0xfff, 0x394, 0xfff, 0xfff, 0xfff,
968 0xfff, 0x52c, 0xfff, 0xfff, 0xfff, 0x392, 0xfff, 0x1e7,
969 0xfff, 0xfff, 0x3f9, 0x3a7, 0xfff, 0x51f, 0xfff, 0x0bb,
970 0x118, 0x3ca, 0xfff, 0x1dd, 0xfff, 0x48b, 0xfff, 0xfff,
971 0xfff, 0xfff, 0x50f, 0xfff, 0x0d6, 0xfff, 0x1fa, 0xfff,
972 0x11e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d7, 0xfff, 0x078,
973 0x008, 0xfff, 0x25d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
974 0x032, 0x33c, 0xfff, 0x4d9, 0x160, 0xfff, 0xfff, 0x300,
975 0x0b1, 0xfff, 0x322, 0xfff, 0x4ec, 0xfff, 0xfff, 0x200,
976 0x00c, 0x369, 0x473, 0xfff, 0xfff, 0x32c, 0xfff, 0xfff,
977 0xfff, 0xfff, 0xfff, 0xfff, 0x53e, 0x3d4, 0x417, 0xfff,
978 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
979 0x34b, 0x001, 0x39a, 0x02c, 0xfff, 0xfff, 0x2ce, 0x00f,
980 0xfff, 0x0ba, 0xfff, 0xfff, 0xfff, 0xfff, 0x060, 0xfff,
981 0x406, 0xfff, 0xfff, 0xfff, 0x4ee, 0x4ac, 0xfff, 0x43f,
982 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x29b, 0xfff, 0xfff,
983 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x216,
984 0x190, 0xfff, 0x396, 0x464, 0xfff, 0xfff, 0x323, 0xfff,
985 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e9, 0xfff, 0x26d,
986 0x2cd, 0x040, 0xfff, 0xfff, 0xfff, 0xfff, 0x38b, 0x3c0,
987 0xfff, 0xfff, 0xfff, 0x1f2, 0xfff, 0x0ea, 0xfff, 0xfff,
988 0x472, 0xfff, 0x1fb, 0xfff, 0xfff, 0x0af, 0x27f, 0xfff,
989 0xfff, 0xfff, 0x479, 0x023, 0xfff, 0x0d8, 0x3b3, 0xfff,
990 0xfff, 0xfff, 0x121, 0xfff, 0xfff, 0x3bf, 0xfff, 0xfff,
991 0x16b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
992 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
993 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
994 0x45a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
995 0xfff, 0x0be, 0xfff, 0xfff, 0xfff, 0x111, 0xfff, 0x220,
996 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
997 0xfff, 0xfff, 0x09b, 0x218, 0xfff, 0x022, 0x202, 0xfff,
998 0x4c8, 0xfff, 0x0ed, 0xfff, 0xfff, 0x182, 0xfff, 0xfff,
999 0xfff, 0x17f, 0x213, 0xfff, 0x321, 0x36a, 0xfff, 0x086,
1000 0xfff, 0xfff, 0xfff, 0x43b, 0x088, 0xfff, 0xfff, 0xfff,
1001 0xfff, 0x26c, 0xfff, 0x2f8, 0x3b4, 0xfff, 0xfff, 0xfff,
1002 0x132, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x333, 0x444,
1003 0x0c1, 0x4d8, 0x46d, 0x264, 0xfff, 0xfff, 0xfff, 0xfff,
1004 0x426, 0xfff, 0xfff, 0xfff, 0xfff, 0x2fe, 0xfff, 0xfff,
1005 0xfff, 0xfff, 0x011, 0xfff, 0x05f, 0xfff, 0xfff, 0xfff,
1006 0xfff, 0x10c, 0x101, 0xfff, 0xfff, 0xfff, 0xfff, 0x110,
1007 0xfff, 0x044, 0x304, 0x361, 0x404, 0xfff, 0x51b, 0x099,
1008 0xfff, 0x440, 0xfff, 0xfff, 0xfff, 0x222, 0xfff, 0xfff,
1009 0xfff, 0xfff, 0x1b5, 0xfff, 0x136, 0x430, 0xfff, 0x1da,
1010 0xfff, 0xfff, 0xfff, 0x043, 0xfff, 0x17c, 0xfff, 0xfff,
1011 0xfff, 0x01c, 0xfff, 0xfff, 0xfff, 0x425, 0x236, 0xfff,
1012 0x317, 0xfff, 0xfff, 0x437, 0x3fc, 0xfff, 0x1f1, 0xfff,
1013 0x324, 0xfff, 0xfff, 0x0ca, 0x306, 0xfff, 0x548, 0xfff,
1014 0x46e, 0xfff, 0xfff, 0xfff, 0x4b8, 0x1c2, 0x286, 0xfff,
1015 0xfff, 0x087, 0x18a, 0x19f, 0xfff, 0xfff, 0xfff, 0xfff,
1016 0x18c, 0xfff, 0x215, 0xfff, 0xfff, 0xfff, 0xfff, 0x283,
1017 0xfff, 0xfff, 0xfff, 0x126, 0xfff, 0xfff, 0x370, 0xfff,
1018 0x53f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x31c, 0xfff,
1019 0x4d1, 0xfff, 0xfff, 0xfff, 0x021, 0xfff, 0x157, 0xfff,
1020 0xfff, 0x028, 0x16e, 0xfff, 0x421, 0xfff, 0x1c6, 0xfff,
1021 0xfff, 0x511, 0xfff, 0xfff, 0x39c, 0x46f, 0x1b2, 0xfff,
1022 0xfff, 0x316, 0xfff, 0xfff, 0x009, 0xfff, 0xfff, 0x195,
1023 0xfff, 0x240, 0x546, 0xfff, 0xfff, 0x520, 0xfff, 0xfff,
1024 0xfff, 0xfff, 0xfff, 0xfff, 0x454, 0xfff, 0xfff, 0xfff,
1025 0x3f3, 0xfff, 0xfff, 0x187, 0xfff, 0x4a9, 0xfff, 0xfff,
1026 0xfff, 0xfff, 0xfff, 0xfff, 0x51c, 0x453, 0x1e6, 0xfff,
1027 0xfff, 0xfff, 0x1b0, 0xfff, 0x477, 0xfff, 0xfff, 0xfff,
1028 0x4fe, 0xfff, 0x32f, 0xfff, 0xfff, 0x15e, 0x1d4, 0xfff,
1029 0x0e5, 0xfff, 0xfff, 0xfff, 0x242, 0x14b, 0x046, 0xfff,
1030 0x3f6, 0x3bb, 0x3e4, 0xfff, 0xfff, 0x2e3, 0xfff, 0x245,
1031 0xfff, 0x149, 0xfff, 0xfff, 0xfff, 0x2db, 0xfff, 0xfff,
1032 0x181, 0xfff, 0x089, 0x2c5, 0xfff, 0x1f5, 0xfff, 0x2d6,
1033 0x507, 0xfff, 0x42d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
1034 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
1035 0x080, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
1036 0xfff, 0xfff, 0xfff, 0xfff, 0x3c3, 0x320, 0xfff, 0x1e1,
1037 0xfff, 0x0f5, 0x13b, 0xfff, 0xfff, 0xfff, 0x003, 0x4da,
1038 0xfff, 0xfff, 0xfff, 0x42c, 0xfff, 0xfff, 0x0cb, 0xfff,
1039 0x536, 0x2c3, 0xfff, 0xfff, 0xfff, 0xfff, 0x199, 0xfff,
1040 0xfff, 0x0c0, 0xfff, 0x01e, 0x497, 0xfff, 0xfff, 0x3e5,
1041 0xfff, 0xfff, 0xfff, 0x0cf, 0xfff, 0x2bd, 0xfff, 0x223,
1042 0xfff, 0x3ff, 0xfff, 0x058, 0x174, 0x3ef, 0xfff, 0x002
1043};
1044
1045static unsigned short err_pos(unsigned short din)
1046{
1047 BUG_ON(din > 4096);
1048 BUG_ON(err_pos_lut[din] == 0xfff);
1049 return err_pos_lut[din];
1050}
1051static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1052{
1053 if ((chk_syndrome_list[0] | chk_syndrome_list[1] |
1054 chk_syndrome_list[2] | chk_syndrome_list[3] |
1055 chk_syndrome_list[4] | chk_syndrome_list[5] |
1056 chk_syndrome_list[6] | chk_syndrome_list[7]) != 0x0) {
1057 return -EINVAL;
1058 } else {
1059 err_info[0] = 0x0;
1060 return 0;
1061 }
1062}
1063static int chk_1_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1064{
1065 unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
1066 tmp0 = gf4096_mul(chk_syndrome_list[1], gf4096_inv(chk_syndrome_list[0]));
1067 tmp1 = gf4096_mul(chk_syndrome_list[2], gf4096_inv(chk_syndrome_list[1]));
1068 tmp2 = gf4096_mul(chk_syndrome_list[3], gf4096_inv(chk_syndrome_list[2]));
1069 tmp3 = gf4096_mul(chk_syndrome_list[4], gf4096_inv(chk_syndrome_list[3]));
1070 tmp4 = gf4096_mul(chk_syndrome_list[5], gf4096_inv(chk_syndrome_list[4]));
1071 tmp5 = gf4096_mul(chk_syndrome_list[6], gf4096_inv(chk_syndrome_list[5]));
1072 tmp6 = gf4096_mul(chk_syndrome_list[7], gf4096_inv(chk_syndrome_list[6]));
1073 if ((tmp0 == tmp1) & (tmp1 == tmp2) & (tmp2 == tmp3) & (tmp3 == tmp4) & (tmp4 == tmp5) & (tmp5 == tmp6)) {
1074 err_info[0] = 0x1; // encode 1-symbol error as 0x1
1075 err_info[1] = err_pos(tmp0);
1076 err_info[1] = (unsigned short)(0x55e - err_info[1]);
1077 err_info[5] = chk_syndrome_list[0];
1078 return 0;
1079 } else
1080 return -EINVAL;
1081}
1082static int chk_2_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1083{
1084 unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
1085 unsigned short coefs[4];
1086 unsigned short err_pats[4];
1087 int found_num_root = 0;
1088 unsigned short bit2_root0, bit2_root1;
1089 unsigned short bit2_root0_inv, bit2_root1_inv;
1090 unsigned short err_loc_eqn, test_root;
1091 unsigned short bit2_loc0, bit2_loc1;
1092 unsigned short bit2_pat0, bit2_pat1;
1093
1094 find_2x2_soln(chk_syndrome_list[1],
1095 chk_syndrome_list[0],
1096 chk_syndrome_list[2], chk_syndrome_list[1], chk_syndrome_list[2], chk_syndrome_list[3], coefs);
1097 for (test_root = 0x1; test_root < 0xfff; test_root++) {
1098 err_loc_eqn =
1099 gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root) ^ 0x1;
1100 if (err_loc_eqn == 0x0) {
1101 if (found_num_root == 0) {
1102 bit2_root0 = test_root;
1103 found_num_root = 1;
1104 } else if (found_num_root == 1) {
1105 bit2_root1 = test_root;
1106 found_num_root = 2;
1107 break;
1108 }
1109 }
1110 }
1111 if (found_num_root != 2)
1112 return -EINVAL;
1113 else {
1114 bit2_root0_inv = gf4096_inv(bit2_root0);
1115 bit2_root1_inv = gf4096_inv(bit2_root1);
1116 find_2bit_err_pats(chk_syndrome_list[0],
1117 chk_syndrome_list[1], bit2_root0_inv, bit2_root1_inv, err_pats);
1118 bit2_pat0 = err_pats[0];
1119 bit2_pat1 = err_pats[1];
1120 //for(x+1)
1121 tmp0 = gf4096_mul(gf4096_mul(bit2_root0_inv, bit2_root0_inv), gf4096_mul(bit2_root0_inv, bit2_root0_inv)); //rinv0^4
1122 tmp1 = gf4096_mul(bit2_root0_inv, tmp0); //rinv0^5
1123 tmp2 = gf4096_mul(bit2_root0_inv, tmp1); //rinv0^6
1124 tmp3 = gf4096_mul(bit2_root0_inv, tmp2); //rinv0^7
1125 tmp4 = gf4096_mul(gf4096_mul(bit2_root1_inv, bit2_root1_inv), gf4096_mul(bit2_root1_inv, bit2_root1_inv)); //rinv1^4
1126 tmp5 = gf4096_mul(bit2_root1_inv, tmp4); //rinv1^5
1127 tmp6 = gf4096_mul(bit2_root1_inv, tmp5); //rinv1^6
1128 tmp7 = gf4096_mul(bit2_root1_inv, tmp6); //rinv1^7
1129 //check if only 2-bit error
1130 if ((chk_syndrome_list[4] ==
1131 (gf4096_mul(bit2_pat0, tmp0) ^
1132 gf4096_mul(bit2_pat1,
1133 tmp4))) & (chk_syndrome_list[5] ==
1134 (gf4096_mul(bit2_pat0, tmp1) ^
1135 gf4096_mul(bit2_pat1,
1136 tmp5))) &
1137 (chk_syndrome_list[6] ==
1138 (gf4096_mul(bit2_pat0, tmp2) ^
1139 gf4096_mul(bit2_pat1,
1140 tmp6))) & (chk_syndrome_list[7] ==
1141 (gf4096_mul(bit2_pat0, tmp3) ^ gf4096_mul(bit2_pat1, tmp7)))) {
1142 if ((err_pos(bit2_root0_inv) == 0xfff) | (err_pos(bit2_root1_inv) == 0xfff)) {
1143 return -EINVAL;
1144 } else {
1145 bit2_loc0 = 0x55e - err_pos(bit2_root0_inv);
1146 bit2_loc1 = 0x55e - err_pos(bit2_root1_inv);
1147 err_info[0] = 0x2; // encode 2-symbol error as 0x2
1148 err_info[1] = bit2_loc0;
1149 err_info[2] = bit2_loc1;
1150 err_info[5] = bit2_pat0;
1151 err_info[6] = bit2_pat1;
1152 return 0;
1153 }
1154 } else
1155 return -EINVAL;
1156 }
1157}
1158static int chk_3_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1159{
1160 unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
1161 unsigned short coefs[4];
1162 unsigned short err_pats[4];
1163 int found_num_root = 0;
1164 unsigned short bit3_root0, bit3_root1, bit3_root2;
1165 unsigned short bit3_root0_inv, bit3_root1_inv, bit3_root2_inv;
1166 unsigned short err_loc_eqn, test_root;
1167
1168 find_3bit_err_coefs(chk_syndrome_list[0], chk_syndrome_list[1],
1169 chk_syndrome_list[2], chk_syndrome_list[3],
1170 chk_syndrome_list[4], chk_syndrome_list[5], coefs);
1171
1172 for (test_root = 0x1; test_root < 0xfff; test_root++) {
1173 err_loc_eqn = gf4096_mul(coefs[2],
1174 gf4096_mul(gf4096_mul(test_root, test_root),
1175 test_root)) ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root))
1176 ^ gf4096_mul(coefs[0], test_root) ^ 0x1;
1177
1178 if (err_loc_eqn == 0x0) {
1179 if (found_num_root == 0) {
1180 bit3_root0 = test_root;
1181 found_num_root = 1;
1182 } else if (found_num_root == 1) {
1183 bit3_root1 = test_root;
1184 found_num_root = 2;
1185 } else if (found_num_root == 2) {
1186 bit3_root2 = test_root;
1187 found_num_root = 3;
1188 break;
1189 }
1190 }
1191 }
1192 if (found_num_root != 3)
1193 return -EINVAL;
1194 else {
1195 bit3_root0_inv = gf4096_inv(bit3_root0);
1196 bit3_root1_inv = gf4096_inv(bit3_root1);
1197 bit3_root2_inv = gf4096_inv(bit3_root2);
1198
1199 find_3bit_err_pats(chk_syndrome_list[0], chk_syndrome_list[1],
1200 chk_syndrome_list[2], bit3_root0_inv,
1201 bit3_root1_inv, bit3_root2_inv, err_pats);
1202
1203 //check if only 3-bit error
1204 tmp0 = gf4096_mul(bit3_root0_inv, bit3_root0_inv);
1205 tmp0 = gf4096_mul(tmp0, tmp0);
1206 tmp0 = gf4096_mul(tmp0, bit3_root0_inv);
1207 tmp0 = gf4096_mul(tmp0, bit3_root0_inv); //rinv0^6
1208 tmp1 = gf4096_mul(tmp0, bit3_root0_inv); //rinv0^7
1209 tmp2 = gf4096_mul(bit3_root1_inv, bit3_root1_inv);
1210 tmp2 = gf4096_mul(tmp2, tmp2);
1211 tmp2 = gf4096_mul(tmp2, bit3_root1_inv);
1212 tmp2 = gf4096_mul(tmp2, bit3_root1_inv); //rinv1^6
1213 tmp3 = gf4096_mul(tmp2, bit3_root1_inv); //rinv1^7
1214 tmp4 = gf4096_mul(bit3_root2_inv, bit3_root2_inv);
1215 tmp4 = gf4096_mul(tmp4, tmp4);
1216 tmp4 = gf4096_mul(tmp4, bit3_root2_inv);
1217 tmp4 = gf4096_mul(tmp4, bit3_root2_inv); //rinv2^6
1218 tmp5 = gf4096_mul(tmp4, bit3_root2_inv); //rinv2^7
1219
1220 //check if only 3 errors
1221 if ((chk_syndrome_list[6] == (gf4096_mul(err_pats[0], tmp0) ^
1222 gf4096_mul(err_pats[1], tmp2) ^
1223 gf4096_mul(err_pats[2], tmp4))) &
1224 (chk_syndrome_list[7] == (gf4096_mul(err_pats[0], tmp1) ^
1225 gf4096_mul(err_pats[1], tmp3) ^ gf4096_mul(err_pats[2], tmp5)))) {
1226 if ((err_pos(bit3_root0_inv) == 0xfff) |
1227 (err_pos(bit3_root1_inv) == 0xfff) | (err_pos(bit3_root2_inv) == 0xfff)) {
1228 return -EINVAL;
1229 } else {
1230 err_info[0] = 0x3;
1231 err_info[1] = (0x55e - err_pos(bit3_root0_inv));
1232 err_info[2] = (0x55e - err_pos(bit3_root1_inv));
1233 err_info[3] = (0x55e - err_pos(bit3_root2_inv));
1234 err_info[5] = err_pats[0];
1235 err_info[6] = err_pats[1];
1236 err_info[7] = err_pats[2];
1237 return 0;
1238 }
1239 } else
1240 return -EINVAL;
1241 }
1242}
1243static int chk_4_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1244{
1245 unsigned short coefs[4];
1246 unsigned short err_pats[4];
1247 int found_num_root = 0;
1248 unsigned short bit4_root0, bit4_root1, bit4_root2, bit4_root3;
1249 unsigned short bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv;
1250 unsigned short err_loc_eqn, test_root;
1251
1252 find_4bit_err_coefs(chk_syndrome_list[0],
1253 chk_syndrome_list[1],
1254 chk_syndrome_list[2],
1255 chk_syndrome_list[3],
1256 chk_syndrome_list[4],
1257 chk_syndrome_list[5], chk_syndrome_list[6], chk_syndrome_list[7], coefs);
1258
1259 for (test_root = 0x1; test_root < 0xfff; test_root++) {
1260 err_loc_eqn =
1261 gf4096_mul(coefs[3],
1262 gf4096_mul(gf4096_mul
1263 (gf4096_mul(test_root, test_root),
1264 test_root),
1265 test_root)) ^ gf4096_mul(coefs[2],
1266 gf4096_mul
1267 (gf4096_mul(test_root, test_root), test_root))
1268 ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root)
1269 ^ 0x1;
1270 if (err_loc_eqn == 0x0) {
1271 if (found_num_root == 0) {
1272 bit4_root0 = test_root;
1273 found_num_root = 1;
1274 } else if (found_num_root == 1) {
1275 bit4_root1 = test_root;
1276 found_num_root = 2;
1277 } else if (found_num_root == 2) {
1278 bit4_root2 = test_root;
1279 found_num_root = 3;
1280 } else {
1281 found_num_root = 4;
1282 bit4_root3 = test_root;
1283 break;
1284 }
1285 }
1286 }
1287 if (found_num_root != 4) {
1288 return -EINVAL;
1289 } else {
1290 bit4_root0_inv = gf4096_inv(bit4_root0);
1291 bit4_root1_inv = gf4096_inv(bit4_root1);
1292 bit4_root2_inv = gf4096_inv(bit4_root2);
1293 bit4_root3_inv = gf4096_inv(bit4_root3);
1294 find_4bit_err_pats(chk_syndrome_list[0],
1295 chk_syndrome_list[1],
1296 chk_syndrome_list[2],
1297 chk_syndrome_list[3],
1298 bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv, err_pats);
1299 err_info[0] = 0x4;
1300 err_info[1] = (0x55e - err_pos(bit4_root0_inv));
1301 err_info[2] = (0x55e - err_pos(bit4_root1_inv));
1302 err_info[3] = (0x55e - err_pos(bit4_root2_inv));
1303 err_info[4] = (0x55e - err_pos(bit4_root3_inv));
1304 err_info[5] = err_pats[0];
1305 err_info[6] = err_pats[1];
1306 err_info[7] = err_pats[2];
1307 err_info[8] = err_pats[3];
1308 return 0;
1309 }
1310}
1311
1312void correct_12bit_symbol(unsigned char *buf, unsigned short sym,
1313 unsigned short val)
1314{
1315 if (unlikely(sym > 1366)) {
1316 printk(KERN_ERR "Error: symbol %d out of range; cannot correct\n", sym);
1317 } else if (sym == 0) {
1318 buf[0] ^= val;
1319 } else if (sym & 1) {
1320 buf[1+(3*(sym-1))/2] ^= (val >> 4);
1321 buf[2+(3*(sym-1))/2] ^= ((val & 0xf) << 4);
1322 } else {
1323 buf[2+(3*(sym-2))/2] ^= (val >> 8);
1324 buf[3+(3*(sym-2))/2] ^= (val & 0xff);
1325 }
1326
1327
1328}
1329
1330int cafe_correct_ecc(unsigned char *buf,
1331 unsigned short *chk_syndrome_list)
1332{
1333 unsigned short err_info[9];
1334 int i;
1335
1336 if (chk_no_err_only(chk_syndrome_list, err_info) &&
1337 chk_1_err_only(chk_syndrome_list, err_info) &&
1338 chk_2_err_only(chk_syndrome_list, err_info) &&
1339 chk_3_err_only(chk_syndrome_list, err_info) &&
1340 chk_4_err_only(chk_syndrome_list, err_info)) {
1341 return -EIO;
1342 }
1343
1344 for (i=0; i < err_info[0]; i++)
1345 correct_12bit_symbol(buf, err_info[1+i], err_info[5+i]);
1346
1347 return err_info[0];
1348}
1349