lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20151217021121.GD631@robwan01-pc.asiapac.arm.com>
Date:	Thu, 17 Dec 2015 02:11:22 +0000
From:	Huang Shijie <shijie.huang@....com>
To:	Han Xu <b45815@...escale.com>
CC:	<dwmw2@...radead.org>, <computersforpeace@...il.com>,
	<boris.brezillon@...e-electrons.com>,
	<fabio.estevam@...escale.com>, <hofrat@...dl.org>,
	<linux-mtd@...ts.infradead.org>, <linux-kernel@...r.kernel.org>,
	<vinod.koul@...el.com>, <dan.j.williams@...el.com>,
	<dmaengine@...r.kernel.org>
Subject: Re: [PATCH v8 6/7] mtd: nand: gpmi: correct bitflip for erased NAND
 page

On Wed, Dec 02, 2015 at 04:47:45PM -0600, Han Xu wrote:
> i.MX6QP and i.MX7D BCH module integrated a new feature to detect the
> bitflip number for erased NAND page. So for these two platform, set the
> erase threshold to ecc_strength and if bitflip detected, GPMI driver will
> correct the data to all 0xFF.
>
> Signed-off-by: Han Xu <b45815@...escale.com>
> ---
>  drivers/mtd/nand/gpmi-nand/bch-regs.h  | 10 ++++++++++
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |  5 +++++
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 24 +++++++++++++++++++++++-
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  5 ++++-
>  4 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h
> index 53e58bc..a84d72b 100644
> --- a/drivers/mtd/nand/gpmi-nand/bch-regs.h
> +++ b/drivers/mtd/nand/gpmi-nand/bch-regs.h
> @@ -30,7 +30,13 @@
>  #define BM_BCH_CTRL_COMPLETE_IRQ             (1 << 0)
>
>  #define HW_BCH_STATUS0                               0x00000010
> +
>  #define HW_BCH_MODE                          0x00000020
> +#define BP_BCH_MODE_ERASE_THRESHOLD          0
> +#define BM_BCH_MODE_ERASE_THRESHOLD  (0xff << BP_BCH_MODE_ERASE_THRESHOLD)
> +#define BF_BCH_MODE_ERASE_THRESHOLD(v)               \
> +     (((v) << BP_BCH_MODE_ERASE_THRESHOLD) & BM_BCH_MODE_ERASE_THRESHOLD)
> +
>  #define HW_BCH_ENCODEPTR                     0x00000030
>  #define HW_BCH_DATAPTR                               0x00000040
>  #define HW_BCH_METAPTR                               0x00000050
> @@ -125,4 +131,8 @@
>       )
>
>  #define HW_BCH_VERSION                               0x00000160
> +#define HW_BCH_DEBUG1                                0x00000170
> +#define BP_BCH_DEBUG1_ERASED_ZERO_COUNT      0
> +#define BM_BCH_DEBUG1_ERASED_ZERO_COUNT              \
> +             (0x1ff << BP_BCH_DEBUG1_ERASED_ZERO_COUNT)
>  #endif
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> index 1f26a79..0548d84 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> @@ -298,6 +298,11 @@ int bch_set_geometry(struct gpmi_nand_data *this)
>                       | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
>                       r->bch_regs + HW_BCH_FLASH0LAYOUT1);
>
> +     /* Set erase threshold to ecc_strength for mx6qp and mx7 */
> +     if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this))
> +             writel(BF_BCH_MODE_ERASE_THRESHOLD(ecc_strength),
> +                     r->bch_regs + HW_BCH_MODE);
> +
>       /* Set *all* chip selects to use layout 0. */
>       writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT);
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 9f67f0f..9dea56e 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -71,6 +71,12 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
>       .max_chain_delay = 12,
>  };
>
> +static const struct gpmi_devdata gpmi_devdata_imx6qp = {
> +     .type = IS_MX6QP,
> +     .bch_max_ecc_strength = 40,
> +     .max_chain_delay = 12,
> +};
> +
>  static const struct gpmi_devdata gpmi_devdata_imx6sx = {
>       .type = IS_MX6SX,
>       .bch_max_ecc_strength = 62,
> @@ -1010,6 +1016,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  {
>       struct gpmi_nand_data *this = chip->priv;
>       struct bch_geometry *nfc_geo = &this->bch_geometry;
> +     void __iomem *bch_regs = this->resources.bch_regs;
>       void          *payload_virt;
>       dma_addr_t    payload_phys;
>       void          *auxiliary_virt;
> @@ -1018,6 +1025,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>       unsigned char *status;
>       unsigned int  max_bitflips = 0;
>       int           ret;
> +     int flag = 0;
>
>       dev_dbg(this->dev, "page number is : %d\n", page);
>       ret = read_page_prepare(this, buf, nfc_geo->payload_size,
> @@ -1050,9 +1058,16 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>       status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
>
>       for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
> -             if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
> +             if (*status == STATUS_GOOD)
>                       continue;
>
> +             if (*status == STATUS_ERASED) {
> +                     if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this))
> +                             if (readl(bch_regs + HW_BCH_DEBUG1))
> +                                     flag = 1;
> +                     continue;
> +             }
> +
>               if (*status == STATUS_UNCORRECTABLE) {
>                       mtd->ecc_stats.failed++;
>                       continue;
> @@ -1081,6 +1096,10 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>                       nfc_geo->payload_size,
>                       payload_virt, payload_phys);
>
> +     /* if bitflip occurred in erased page, change data to all 0xff */
> +     if (flag)
> +             memset(buf, 0xff, nfc_geo->payload_size);
> +
>       return max_bitflips;
>  }
>
> @@ -1990,6 +2009,9 @@ static const struct of_device_id gpmi_nand_id_table[] = {
>               .compatible = "fsl,imx6q-gpmi-nand",
>               .data = &gpmi_devdata_imx6q,
>       }, {
> +             .compatible = "fsl,imx6qp-gpmi-nand",
> +             .data = (void *)&gpmi_devdata_imx6qp,
> +     }, {
>               .compatible = "fsl,imx6sx-gpmi-nand",
>               .data = &gpmi_devdata_imx6sx,
>       }, {
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> index 58b3d69..149a442 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> @@ -123,6 +123,7 @@ enum gpmi_type {
>       IS_MX23,
>       IS_MX28,
>       IS_MX6Q,
> +     IS_MX6QP,
>       IS_MX6SX,
>       IS_MX7D,
>  };
> @@ -306,9 +307,11 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
>  #define GPMI_IS_MX23(x)              ((x)->devdata->type == IS_MX23)
>  #define GPMI_IS_MX28(x)              ((x)->devdata->type == IS_MX28)
>  #define GPMI_IS_MX6Q(x)              ((x)->devdata->type == IS_MX6Q)
> +#define GPMI_IS_MX6QP(x)     ((x)->devdata->type == IS_MX6QP)
>  #define GPMI_IS_MX6SX(x)     ((x)->devdata->type == IS_MX6SX)
>  #define GPMI_IS_MX7D(x)              ((x)->devdata->type == IS_MX7D)
>
> -#define GPMI_IS_MX6(x)               (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x))
> +#define GPMI_IS_MX6(x)               (GPMI_IS_MX6Q(x) || GPMI_IS_MX6QP(x)\
> +        || GPMI_IS_MX6SX(x))
>  #define GPMI_IS_MX7(x)               (GPMI_IS_MX7D(x))
>  #endif
> --
> 1.9.1
>
Very good feature.

Acked-by: Huang Shijie <shijie.huang@....com>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ