OSDN Git Service

crypto: atmel-tdes - Map driver data flags to Mode Register
authorTudor Ambarus <tudor.ambarus@microchip.com>
Thu, 5 Dec 2019 09:53:56 +0000 (09:53 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 11 Dec 2019 08:46:22 +0000 (16:46 +0800)
Simplifies the configuration of the TDES IP.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/atmel-tdes.c

index d125927..cc57339 100644 (file)
 #define ATMEL_TDES_PRIORITY    300
 
 /* TDES flags  */
-#define TDES_FLAGS_MODE_MASK           0x00ff
-#define TDES_FLAGS_ENCRYPT     BIT(0)
-#define TDES_FLAGS_CBC         BIT(1)
-#define TDES_FLAGS_CFB         BIT(2)
-#define TDES_FLAGS_CFB8                BIT(3)
-#define TDES_FLAGS_CFB16       BIT(4)
-#define TDES_FLAGS_CFB32       BIT(5)
-#define TDES_FLAGS_CFB64       BIT(6)
-#define TDES_FLAGS_OFB         BIT(7)
-
-#define TDES_FLAGS_INIT                BIT(16)
-#define TDES_FLAGS_FAST                BIT(17)
-#define TDES_FLAGS_BUSY                BIT(18)
-#define TDES_FLAGS_DMA         BIT(19)
+/* Reserve bits [17:16], [13:12], [2:0] for AES Mode Register */
+#define TDES_FLAGS_ENCRYPT     TDES_MR_CYPHER_ENC
+#define TDES_FLAGS_OPMODE_MASK (TDES_MR_OPMOD_MASK | TDES_MR_CFBS_MASK)
+#define TDES_FLAGS_ECB         TDES_MR_OPMOD_ECB
+#define TDES_FLAGS_CBC         TDES_MR_OPMOD_CBC
+#define TDES_FLAGS_OFB         TDES_MR_OPMOD_OFB
+#define TDES_FLAGS_CFB64       (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_64b)
+#define TDES_FLAGS_CFB32       (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_32b)
+#define TDES_FLAGS_CFB16       (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_16b)
+#define TDES_FLAGS_CFB8                (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_8b)
+
+#define TDES_FLAGS_MODE_MASK   (TDES_FLAGS_OPMODE_MASK | TDES_FLAGS_ENCRYPT)
+
+#define TDES_FLAGS_INIT                BIT(3)
+#define TDES_FLAGS_FAST                BIT(4)
+#define TDES_FLAGS_BUSY                BIT(5)
+#define TDES_FLAGS_DMA         BIT(6)
 
 #define ATMEL_TDES_QUEUE_LENGTH        50
 
@@ -287,35 +290,15 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
                valmr |= TDES_MR_TDESMOD_DES;
        }
 
-       if (dd->flags & TDES_FLAGS_CBC) {
-               valmr |= TDES_MR_OPMOD_CBC;
-       } else if (dd->flags & TDES_FLAGS_CFB) {
-               valmr |= TDES_MR_OPMOD_CFB;
-
-               if (dd->flags & TDES_FLAGS_CFB8)
-                       valmr |= TDES_MR_CFBS_8b;
-               else if (dd->flags & TDES_FLAGS_CFB16)
-                       valmr |= TDES_MR_CFBS_16b;
-               else if (dd->flags & TDES_FLAGS_CFB32)
-                       valmr |= TDES_MR_CFBS_32b;
-               else if (dd->flags & TDES_FLAGS_CFB64)
-                       valmr |= TDES_MR_CFBS_64b;
-       } else if (dd->flags & TDES_FLAGS_OFB) {
-               valmr |= TDES_MR_OPMOD_OFB;
-       }
-
-       if ((dd->flags & TDES_FLAGS_ENCRYPT) || (dd->flags & TDES_FLAGS_OFB))
-               valmr |= TDES_MR_CYPHER_ENC;
+       valmr |= dd->flags & TDES_FLAGS_MODE_MASK;
 
        atmel_tdes_write(dd, TDES_MR, valmr);
 
        atmel_tdes_write_n(dd, TDES_KEY1W1R, dd->ctx->key,
                                                dd->ctx->keylen >> 2);
 
-       if (((dd->flags & TDES_FLAGS_CBC) || (dd->flags & TDES_FLAGS_CFB) ||
-               (dd->flags & TDES_FLAGS_OFB)) && dd->req->iv) {
+       if (dd->req->iv && (valmr & TDES_MR_OPMOD_MASK) != TDES_MR_OPMOD_ECB)
                atmel_tdes_write_n(dd, TDES_IV1R, (void *)dd->req->iv, 2);
-       }
 
        return 0;
 }
@@ -406,6 +389,7 @@ static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
 {
        struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
        struct atmel_tdes_dev *dd = ctx->dd;
+       struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(dd->req);
        int len32;
 
        dd->dma_size = length;
@@ -415,12 +399,19 @@ static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
                                           DMA_TO_DEVICE);
        }
 
-       if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB8))
+       switch (rctx->mode & TDES_FLAGS_OPMODE_MASK) {
+       case TDES_FLAGS_CFB8:
                len32 = DIV_ROUND_UP(length, sizeof(u8));
-       else if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB16))
+               break;
+
+       case TDES_FLAGS_CFB16:
                len32 = DIV_ROUND_UP(length, sizeof(u16));
-       else
+               break;
+
+       default:
                len32 = DIV_ROUND_UP(length, sizeof(u32));
+               break;
+       }
 
        atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
        atmel_tdes_write(dd, TDES_TPR, dma_addr_in);
@@ -442,8 +433,10 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
 {
        struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
        struct atmel_tdes_dev *dd = ctx->dd;
+       struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(dd->req);
        struct scatterlist sg[2];
        struct dma_async_tx_descriptor  *in_desc, *out_desc;
+       enum dma_slave_buswidth addr_width;
 
        dd->dma_size = length;
 
@@ -452,23 +445,23 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
                                           DMA_TO_DEVICE);
        }
 
-       if (dd->flags & TDES_FLAGS_CFB8) {
-               dd->dma_lch_in.dma_conf.dst_addr_width =
-                       DMA_SLAVE_BUSWIDTH_1_BYTE;
-               dd->dma_lch_out.dma_conf.src_addr_width =
-                       DMA_SLAVE_BUSWIDTH_1_BYTE;
-       } else if (dd->flags & TDES_FLAGS_CFB16) {
-               dd->dma_lch_in.dma_conf.dst_addr_width =
-                       DMA_SLAVE_BUSWIDTH_2_BYTES;
-               dd->dma_lch_out.dma_conf.src_addr_width =
-                       DMA_SLAVE_BUSWIDTH_2_BYTES;
-       } else {
-               dd->dma_lch_in.dma_conf.dst_addr_width =
-                       DMA_SLAVE_BUSWIDTH_4_BYTES;
-               dd->dma_lch_out.dma_conf.src_addr_width =
-                       DMA_SLAVE_BUSWIDTH_4_BYTES;
+       switch (rctx->mode & TDES_FLAGS_OPMODE_MASK) {
+       case TDES_FLAGS_CFB8:
+               addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+               break;
+
+       case TDES_FLAGS_CFB16:
+               addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+               break;
+
+       default:
+               addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+               break;
        }
 
+       dd->dma_lch_in.dma_conf.dst_addr_width = addr_width;
+       dd->dma_lch_out.dma_conf.src_addr_width = addr_width;
+
        dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf);
        dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf);
 
@@ -703,30 +696,38 @@ static int atmel_tdes_crypt(struct skcipher_request *req, unsigned long mode)
        struct atmel_tdes_ctx *ctx = crypto_skcipher_ctx(skcipher);
        struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(req);
 
-       if (mode & TDES_FLAGS_CFB8) {
+       switch (mode & TDES_FLAGS_OPMODE_MASK) {
+       case TDES_FLAGS_CFB8:
                if (!IS_ALIGNED(req->cryptlen, CFB8_BLOCK_SIZE)) {
                        pr_err("request size is not exact amount of CFB8 blocks\n");
                        return -EINVAL;
                }
                ctx->block_size = CFB8_BLOCK_SIZE;
-       } else if (mode & TDES_FLAGS_CFB16) {
+               break;
+
+       case TDES_FLAGS_CFB16:
                if (!IS_ALIGNED(req->cryptlen, CFB16_BLOCK_SIZE)) {
                        pr_err("request size is not exact amount of CFB16 blocks\n");
                        return -EINVAL;
                }
                ctx->block_size = CFB16_BLOCK_SIZE;
-       } else if (mode & TDES_FLAGS_CFB32) {
+               break;
+
+       case TDES_FLAGS_CFB32:
                if (!IS_ALIGNED(req->cryptlen, CFB32_BLOCK_SIZE)) {
                        pr_err("request size is not exact amount of CFB32 blocks\n");
                        return -EINVAL;
                }
                ctx->block_size = CFB32_BLOCK_SIZE;
-       } else {
+               break;
+
+       default:
                if (!IS_ALIGNED(req->cryptlen, DES_BLOCK_SIZE)) {
                        pr_err("request size is not exact amount of DES blocks\n");
                        return -EINVAL;
                }
                ctx->block_size = DES_BLOCK_SIZE;
+               break;
        }
 
        rctx->mode = mode;
@@ -833,17 +834,17 @@ static int atmel_tdes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 
 static int atmel_tdes_ecb_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT);
+       return atmel_tdes_crypt(req, TDES_FLAGS_ECB | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_ecb_decrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, 0);
+       return atmel_tdes_crypt(req, TDES_FLAGS_ECB);
 }
 
 static int atmel_tdes_cbc_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CBC);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CBC | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_cbc_decrypt(struct skcipher_request *req)
@@ -852,50 +853,47 @@ static int atmel_tdes_cbc_decrypt(struct skcipher_request *req)
 }
 static int atmel_tdes_cfb_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB64 | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_cfb_decrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_CFB);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB64);
 }
 
 static int atmel_tdes_cfb8_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
-                                               TDES_FLAGS_CFB8);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB8 | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_cfb8_decrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB8);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB8);
 }
 
 static int atmel_tdes_cfb16_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
-                                               TDES_FLAGS_CFB16);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB16 | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_cfb16_decrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB16);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB16);
 }
 
 static int atmel_tdes_cfb32_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
-                                               TDES_FLAGS_CFB32);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB32 | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_cfb32_decrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB32);
+       return atmel_tdes_crypt(req, TDES_FLAGS_CFB32);
 }
 
 static int atmel_tdes_ofb_encrypt(struct skcipher_request *req)
 {
-       return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_OFB);
+       return atmel_tdes_crypt(req, TDES_FLAGS_OFB | TDES_FLAGS_ENCRYPT);
 }
 
 static int atmel_tdes_ofb_decrypt(struct skcipher_request *req)