From: Bastien Curutchet <bastien.curutchet@bootlin.com>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
Richard Weinberger <richard@nod.at>,
Vignesh Raghavendra <vigneshr@ti.com>,
Michal Simek <michal.simek@amd.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
Bastien Curutchet <bastien.curutchet@bootlin.com>
Subject: [PATCH 1/4] nand: hamming: Replace sm_order boolean with enum
Date: Thu, 23 Jul 2026 15:41:01 +0200 [thread overview]
Message-ID: <20260723-mix-ecc-v1-1-7361c3baeb07@bootlin.com> (raw)
In-Reply-To: <20260723-mix-ecc-v1-0-7361c3baeb07@bootlin.com>
The ECC bit ordering with Hamming code isn't standardized so we
can find several kind of ordering. So far two ordering are handled: the
'regular' one and the 'smart media' one. The 'smart media' ordering is
selected through the sm_order boolean. Using a boolean to choose the bit
ordering prevents from supporting more than two ECC bit orderings.
Create a new enum to represent the supported ECC bit ordering for
Hamming code.
Replace the sm_order boolean with this enum.
Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
---
drivers/mtd/nand/ecc-sw-hamming.c | 29 ++++++++++++++++++-----------
drivers/mtd/nand/raw/nand_base.c | 4 +++-
include/linux/mtd/nand-ecc-sw-hamming.h | 19 +++++++++++++------
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/drivers/mtd/nand/ecc-sw-hamming.c b/drivers/mtd/nand/ecc-sw-hamming.c
index 460acc1029c3..d4127e30726e 100644
--- a/drivers/mtd/nand/ecc-sw-hamming.c
+++ b/drivers/mtd/nand/ecc-sw-hamming.c
@@ -113,7 +113,7 @@ static const char addressbits[256] = {
};
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
- unsigned char *code, bool sm_order)
+ unsigned char *code, enum ecc_hamming_order ecc_order)
{
const u32 *bp = (uint32_t *)buf;
const u32 eccsize_mult = (step_size == 256) ? 1 : 2;
@@ -309,7 +309,8 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
* possible, but benchmarks showed that on the system this is developed
* the code below is the fastest
*/
- if (sm_order) {
+ switch (ecc_order) {
+ case ECC_HAMMING_SM_ORDER:
code[0] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
(invparity[rp5] << 5) | (invparity[rp4] << 4) |
(invparity[rp3] << 3) | (invparity[rp2] << 2) |
@@ -318,7 +319,8 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
(invparity[rp13] << 5) | (invparity[rp12] << 4) |
(invparity[rp11] << 3) | (invparity[rp10] << 2) |
(invparity[rp9] << 1) | (invparity[rp8]);
- } else {
+ break;
+ case ECC_HAMMING_REGULAR_ORDER:
code[1] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
(invparity[rp5] << 5) | (invparity[rp4] << 4) |
(invparity[rp3] << 3) | (invparity[rp2] << 2) |
@@ -327,6 +329,7 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
(invparity[rp13] << 5) | (invparity[rp12] << 4) |
(invparity[rp11] << 3) | (invparity[rp10] << 2) |
(invparity[rp9] << 1) | (invparity[rp8]);
+ break;
}
if (eccsize_mult == 1)
@@ -364,15 +367,16 @@ int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
{
struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
unsigned int step_size = nand->ecc.ctx.conf.step_size;
- bool sm_order = engine_conf ? engine_conf->sm_order : false;
+ enum ecc_hamming_order order = engine_conf ? engine_conf->ecc_order :
+ ECC_HAMMING_REGULAR_ORDER;
- return ecc_sw_hamming_calculate(buf, step_size, code, sm_order);
+ return ecc_sw_hamming_calculate(buf, step_size, code, order);
}
EXPORT_SYMBOL(nand_ecc_sw_hamming_calculate);
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
unsigned char *calc_ecc, unsigned int step_size,
- bool sm_order)
+ enum ecc_hamming_order ecc_order)
{
const u32 eccsize_mult = step_size >> 8;
unsigned char b0, b1, b2, bit_addr;
@@ -383,14 +387,16 @@ int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
* we might need the xor result more than once,
* so keep them in a local var
*/
- if (sm_order) {
+ switch (ecc_order) {
+ case ECC_HAMMING_SM_ORDER:
b0 = read_ecc[0] ^ calc_ecc[0];
b1 = read_ecc[1] ^ calc_ecc[1];
- } else {
+ break;
+ case ECC_HAMMING_REGULAR_ORDER:
b0 = read_ecc[1] ^ calc_ecc[1];
b1 = read_ecc[0] ^ calc_ecc[0];
+ break;
}
-
b2 = read_ecc[2] ^ calc_ecc[2];
/* check if there are any bitfaults */
@@ -457,10 +463,11 @@ int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
{
struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
unsigned int step_size = nand->ecc.ctx.conf.step_size;
- bool sm_order = engine_conf ? engine_conf->sm_order : false;
+ enum ecc_hamming_order ecc_order = engine_conf ? engine_conf->ecc_order :
+ ECC_HAMMING_REGULAR_ORDER;
return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, step_size,
- sm_order);
+ ecc_order);
}
EXPORT_SYMBOL(nand_ecc_sw_hamming_correct);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index a5b278ab9384..f6b6a4fa2b1f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5657,7 +5657,9 @@ int rawnand_sw_hamming_init(struct nand_chip *chip)
engine_conf = base->ecc.ctx.priv;
if (chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER)
- engine_conf->sm_order = true;
+ engine_conf->ecc_order = ECC_HAMMING_SM_ORDER;
+ else
+ engine_conf->ecc_order = ECC_HAMMING_REGULAR_ORDER;
chip->ecc.size = base->ecc.ctx.conf.step_size;
chip->ecc.strength = base->ecc.ctx.conf.strength;
diff --git a/include/linux/mtd/nand-ecc-sw-hamming.h b/include/linux/mtd/nand-ecc-sw-hamming.h
index 2aa2f8ef68d2..ac6f28f35f77 100644
--- a/include/linux/mtd/nand-ecc-sw-hamming.h
+++ b/include/linux/mtd/nand-ecc-sw-hamming.h
@@ -12,6 +12,11 @@
#include <linux/mtd/nand.h>
+enum ecc_hamming_order {
+ ECC_HAMMING_REGULAR_ORDER = 0,
+ ECC_HAMMING_SM_ORDER,
+};
+
/**
* struct nand_ecc_sw_hamming_conf - private software Hamming ECC engine structure
* @req_ctx: Save request context and tweak the original request to fit the
@@ -19,14 +24,14 @@
* @code_size: Number of bytes needed to store a code (one code per step)
* @calc_buf: Buffer to use when calculating ECC bytes
* @code_buf: Buffer to use when reading (raw) ECC bytes from the chip
- * @sm_order: Smart Media special ordering
+ * @ecc_order: ECC ordering
*/
struct nand_ecc_sw_hamming_conf {
struct nand_ecc_req_tweak_ctx req_ctx;
unsigned int code_size;
u8 *calc_buf;
u8 *code_buf;
- unsigned int sm_order;
+ enum ecc_hamming_order ecc_order;
};
#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
@@ -34,13 +39,13 @@ struct nand_ecc_sw_hamming_conf {
int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand);
void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand);
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
- unsigned char *code, bool sm_order);
+ unsigned char *code, enum ecc_hamming_order ecc_order);
int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
const unsigned char *buf,
unsigned char *code);
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
unsigned char *calc_ecc, unsigned int step_size,
- bool sm_order);
+ enum ecc_hamming_order ecc_order);
int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
unsigned char *read_ecc,
unsigned char *calc_ecc);
@@ -56,7 +61,8 @@ static inline void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand) {}
static inline int ecc_sw_hamming_calculate(const unsigned char *buf,
unsigned int step_size,
- unsigned char *code, bool sm_order)
+ unsigned char *code,
+ enum ecc_hamming_order ecc_order)
{
return -ENOTSUPP;
}
@@ -71,7 +77,8 @@ static inline int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
static inline int ecc_sw_hamming_correct(unsigned char *buf,
unsigned char *read_ecc,
unsigned char *calc_ecc,
- unsigned int step_size, bool sm_order)
+ unsigned int step_size,
+ enum ecc_hamming_order ecc_order)
{
return -ENOTSUPP;
}
--
2.55.0
WARNING: multiple messages have this Message-ID (diff)
From: Bastien Curutchet <bastien.curutchet@bootlin.com>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
Richard Weinberger <richard@nod.at>,
Vignesh Raghavendra <vigneshr@ti.com>,
Michal Simek <michal.simek@amd.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
Bastien Curutchet <bastien.curutchet@bootlin.com>
Subject: [PATCH 1/4] nand: hamming: Replace sm_order boolean with enum
Date: Thu, 23 Jul 2026 15:41:01 +0200 [thread overview]
Message-ID: <20260723-mix-ecc-v1-1-7361c3baeb07@bootlin.com> (raw)
In-Reply-To: <20260723-mix-ecc-v1-0-7361c3baeb07@bootlin.com>
The ECC bit ordering with Hamming code isn't standardized so we
can find several kind of ordering. So far two ordering are handled: the
'regular' one and the 'smart media' one. The 'smart media' ordering is
selected through the sm_order boolean. Using a boolean to choose the bit
ordering prevents from supporting more than two ECC bit orderings.
Create a new enum to represent the supported ECC bit ordering for
Hamming code.
Replace the sm_order boolean with this enum.
Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
---
drivers/mtd/nand/ecc-sw-hamming.c | 29 ++++++++++++++++++-----------
drivers/mtd/nand/raw/nand_base.c | 4 +++-
include/linux/mtd/nand-ecc-sw-hamming.h | 19 +++++++++++++------
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/drivers/mtd/nand/ecc-sw-hamming.c b/drivers/mtd/nand/ecc-sw-hamming.c
index 460acc1029c3..d4127e30726e 100644
--- a/drivers/mtd/nand/ecc-sw-hamming.c
+++ b/drivers/mtd/nand/ecc-sw-hamming.c
@@ -113,7 +113,7 @@ static const char addressbits[256] = {
};
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
- unsigned char *code, bool sm_order)
+ unsigned char *code, enum ecc_hamming_order ecc_order)
{
const u32 *bp = (uint32_t *)buf;
const u32 eccsize_mult = (step_size == 256) ? 1 : 2;
@@ -309,7 +309,8 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
* possible, but benchmarks showed that on the system this is developed
* the code below is the fastest
*/
- if (sm_order) {
+ switch (ecc_order) {
+ case ECC_HAMMING_SM_ORDER:
code[0] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
(invparity[rp5] << 5) | (invparity[rp4] << 4) |
(invparity[rp3] << 3) | (invparity[rp2] << 2) |
@@ -318,7 +319,8 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
(invparity[rp13] << 5) | (invparity[rp12] << 4) |
(invparity[rp11] << 3) | (invparity[rp10] << 2) |
(invparity[rp9] << 1) | (invparity[rp8]);
- } else {
+ break;
+ case ECC_HAMMING_REGULAR_ORDER:
code[1] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
(invparity[rp5] << 5) | (invparity[rp4] << 4) |
(invparity[rp3] << 3) | (invparity[rp2] << 2) |
@@ -327,6 +329,7 @@ int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
(invparity[rp13] << 5) | (invparity[rp12] << 4) |
(invparity[rp11] << 3) | (invparity[rp10] << 2) |
(invparity[rp9] << 1) | (invparity[rp8]);
+ break;
}
if (eccsize_mult == 1)
@@ -364,15 +367,16 @@ int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
{
struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
unsigned int step_size = nand->ecc.ctx.conf.step_size;
- bool sm_order = engine_conf ? engine_conf->sm_order : false;
+ enum ecc_hamming_order order = engine_conf ? engine_conf->ecc_order :
+ ECC_HAMMING_REGULAR_ORDER;
- return ecc_sw_hamming_calculate(buf, step_size, code, sm_order);
+ return ecc_sw_hamming_calculate(buf, step_size, code, order);
}
EXPORT_SYMBOL(nand_ecc_sw_hamming_calculate);
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
unsigned char *calc_ecc, unsigned int step_size,
- bool sm_order)
+ enum ecc_hamming_order ecc_order)
{
const u32 eccsize_mult = step_size >> 8;
unsigned char b0, b1, b2, bit_addr;
@@ -383,14 +387,16 @@ int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
* we might need the xor result more than once,
* so keep them in a local var
*/
- if (sm_order) {
+ switch (ecc_order) {
+ case ECC_HAMMING_SM_ORDER:
b0 = read_ecc[0] ^ calc_ecc[0];
b1 = read_ecc[1] ^ calc_ecc[1];
- } else {
+ break;
+ case ECC_HAMMING_REGULAR_ORDER:
b0 = read_ecc[1] ^ calc_ecc[1];
b1 = read_ecc[0] ^ calc_ecc[0];
+ break;
}
-
b2 = read_ecc[2] ^ calc_ecc[2];
/* check if there are any bitfaults */
@@ -457,10 +463,11 @@ int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
{
struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
unsigned int step_size = nand->ecc.ctx.conf.step_size;
- bool sm_order = engine_conf ? engine_conf->sm_order : false;
+ enum ecc_hamming_order ecc_order = engine_conf ? engine_conf->ecc_order :
+ ECC_HAMMING_REGULAR_ORDER;
return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, step_size,
- sm_order);
+ ecc_order);
}
EXPORT_SYMBOL(nand_ecc_sw_hamming_correct);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index a5b278ab9384..f6b6a4fa2b1f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5657,7 +5657,9 @@ int rawnand_sw_hamming_init(struct nand_chip *chip)
engine_conf = base->ecc.ctx.priv;
if (chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER)
- engine_conf->sm_order = true;
+ engine_conf->ecc_order = ECC_HAMMING_SM_ORDER;
+ else
+ engine_conf->ecc_order = ECC_HAMMING_REGULAR_ORDER;
chip->ecc.size = base->ecc.ctx.conf.step_size;
chip->ecc.strength = base->ecc.ctx.conf.strength;
diff --git a/include/linux/mtd/nand-ecc-sw-hamming.h b/include/linux/mtd/nand-ecc-sw-hamming.h
index 2aa2f8ef68d2..ac6f28f35f77 100644
--- a/include/linux/mtd/nand-ecc-sw-hamming.h
+++ b/include/linux/mtd/nand-ecc-sw-hamming.h
@@ -12,6 +12,11 @@
#include <linux/mtd/nand.h>
+enum ecc_hamming_order {
+ ECC_HAMMING_REGULAR_ORDER = 0,
+ ECC_HAMMING_SM_ORDER,
+};
+
/**
* struct nand_ecc_sw_hamming_conf - private software Hamming ECC engine structure
* @req_ctx: Save request context and tweak the original request to fit the
@@ -19,14 +24,14 @@
* @code_size: Number of bytes needed to store a code (one code per step)
* @calc_buf: Buffer to use when calculating ECC bytes
* @code_buf: Buffer to use when reading (raw) ECC bytes from the chip
- * @sm_order: Smart Media special ordering
+ * @ecc_order: ECC ordering
*/
struct nand_ecc_sw_hamming_conf {
struct nand_ecc_req_tweak_ctx req_ctx;
unsigned int code_size;
u8 *calc_buf;
u8 *code_buf;
- unsigned int sm_order;
+ enum ecc_hamming_order ecc_order;
};
#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
@@ -34,13 +39,13 @@ struct nand_ecc_sw_hamming_conf {
int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand);
void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand);
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
- unsigned char *code, bool sm_order);
+ unsigned char *code, enum ecc_hamming_order ecc_order);
int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
const unsigned char *buf,
unsigned char *code);
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
unsigned char *calc_ecc, unsigned int step_size,
- bool sm_order);
+ enum ecc_hamming_order ecc_order);
int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
unsigned char *read_ecc,
unsigned char *calc_ecc);
@@ -56,7 +61,8 @@ static inline void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand) {}
static inline int ecc_sw_hamming_calculate(const unsigned char *buf,
unsigned int step_size,
- unsigned char *code, bool sm_order)
+ unsigned char *code,
+ enum ecc_hamming_order ecc_order)
{
return -ENOTSUPP;
}
@@ -71,7 +77,8 @@ static inline int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
static inline int ecc_sw_hamming_correct(unsigned char *buf,
unsigned char *read_ecc,
unsigned char *calc_ecc,
- unsigned int step_size, bool sm_order)
+ unsigned int step_size,
+ enum ecc_hamming_order ecc_order)
{
return -ENOTSUPP;
}
--
2.55.0
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
next prev parent reply other threads:[~2026-07-23 13:41 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 13:41 [PATCH 0/4] rawnand: pl35x: Implement mixed ECC Bastien Curutchet
2026-07-23 13:41 ` Bastien Curutchet
2026-07-23 13:41 ` Bastien Curutchet [this message]
2026-07-23 13:41 ` [PATCH 1/4] nand: hamming: Replace sm_order boolean with enum Bastien Curutchet
2026-07-23 13:41 ` [PATCH 2/4] nand: hamming: Add support for the PL35x ECC bit ordering Bastien Curutchet
2026-07-23 13:41 ` Bastien Curutchet
2026-07-23 13:41 ` [PATCH 3/4] rawnand: base: Export nand_read_page_swecc Bastien Curutchet
2026-07-23 13:41 ` Bastien Curutchet
2026-07-23 13:41 ` [PATCH 4/4] rawnand: pl35x: Implement mixed ECC computing Bastien Curutchet
2026-07-23 13:41 ` Bastien Curutchet
2026-08-07 14:01 ` [PATCH 0/4] rawnand: pl35x: Implement mixed ECC Miquel Raynal
2026-08-07 14:01 ` Miquel Raynal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260723-mix-ecc-v1-1-7361c3baeb07@bootlin.com \
--to=bastien.curutchet@bootlin.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=michal.simek@amd.com \
--cc=miquel.raynal@bootlin.com \
--cc=richard@nod.at \
--cc=thomas.petazzoni@bootlin.com \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.