rslib.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Generic Reed Solomon encoder / decoder library
  4. *
  5. * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
  6. *
  7. * RS code lifted from reed solomon library written by Phil Karn
  8. * Copyright 2002 Phil Karn, KA9Q
  9. */
  10. #ifndef _RSLIB_H_
  11. #define _RSLIB_H_
  12. #include <linux/list.h>
  13. #include <linux/types.h> /* for gfp_t */
  14. #include <linux/gfp.h> /* for GFP_KERNEL */
  15. /**
  16. * struct rs_codec - rs codec data
  17. *
  18. * @mm: Bits per symbol
  19. * @nn: Symbols per block (= (1<<mm)-1)
  20. * @alpha_to: log lookup table
  21. * @index_of: Antilog lookup table
  22. * @genpoly: Generator polynomial
  23. * @nroots: Number of generator roots = number of parity symbols
  24. * @fcr: First consecutive root, index form
  25. * @prim: Primitive element, index form
  26. * @iprim: prim-th root of 1, index form
  27. * @gfpoly: The primitive generator polynominal
  28. * @gffunc: Function to generate the field, if non-canonical representation
  29. * @users: Users of this structure
  30. * @list: List entry for the rs codec list
  31. */
  32. struct rs_codec {
  33. int mm;
  34. int nn;
  35. uint16_t *alpha_to;
  36. uint16_t *index_of;
  37. uint16_t *genpoly;
  38. int nroots;
  39. int fcr;
  40. int prim;
  41. int iprim;
  42. int gfpoly;
  43. int (*gffunc)(int);
  44. int users;
  45. struct list_head list;
  46. };
  47. /**
  48. * struct rs_control - rs control structure per instance
  49. * @codec: The codec used for this instance
  50. * @buffers: Internal scratch buffers used in calls to decode_rs()
  51. */
  52. struct rs_control {
  53. struct rs_codec *codec;
  54. uint16_t buffers[];
  55. };
  56. /* General purpose RS codec, 8-bit data width, symbol width 1-15 bit */
  57. #ifdef CONFIG_REED_SOLOMON_ENC8
  58. int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
  59. uint16_t invmsk);
  60. #endif
  61. #ifdef CONFIG_REED_SOLOMON_DEC8
  62. int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
  63. uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
  64. uint16_t *corr);
  65. #endif
  66. /* General purpose RS codec, 16-bit data width, symbol width 1-15 bit */
  67. #ifdef CONFIG_REED_SOLOMON_ENC16
  68. int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par,
  69. uint16_t invmsk);
  70. #endif
  71. #ifdef CONFIG_REED_SOLOMON_DEC16
  72. int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
  73. uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
  74. uint16_t *corr);
  75. #endif
  76. struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim,
  77. int nroots, gfp_t gfp);
  78. /**
  79. * init_rs - Create a RS control struct and initialize it
  80. * @symsize: the symbol size (number of bits)
  81. * @gfpoly: the extended Galois field generator polynomial coefficients,
  82. * with the 0th coefficient in the low order bit. The polynomial
  83. * must be primitive;
  84. * @fcr: the first consecutive root of the rs code generator polynomial
  85. * in index form
  86. * @prim: primitive element to generate polynomial roots
  87. * @nroots: RS code generator polynomial degree (number of roots)
  88. *
  89. * Allocations use GFP_KERNEL.
  90. */
  91. static inline struct rs_control *init_rs(int symsize, int gfpoly, int fcr,
  92. int prim, int nroots)
  93. {
  94. return init_rs_gfp(symsize, gfpoly, fcr, prim, nroots, GFP_KERNEL);
  95. }
  96. struct rs_control *init_rs_non_canonical(int symsize, int (*func)(int),
  97. int fcr, int prim, int nroots);
  98. /* Release a rs control structure */
  99. void free_rs(struct rs_control *rs);
  100. /** modulo replacement for galois field arithmetics
  101. *
  102. * @rs: Pointer to the RS codec
  103. * @x: the value to reduce
  104. *
  105. * where
  106. * rs->mm = number of bits per symbol
  107. * rs->nn = (2^rs->mm) - 1
  108. *
  109. * Simple arithmetic modulo would return a wrong result for values
  110. * >= 3 * rs->nn
  111. */
  112. static inline int rs_modnn(struct rs_codec *rs, int x)
  113. {
  114. while (x >= rs->nn) {
  115. x -= rs->nn;
  116. x = (x >> rs->mm) + (x & rs->nn);
  117. }
  118. return x;
  119. }
  120. #endif