[HIFN]: Fix data alignment checks
[safe/jmp/linux-2.6] / drivers / crypto / hifn_795x.c
index dfbf24c..4428e8e 100644 (file)
@@ -369,6 +369,8 @@ static atomic_t hifn_dev_number;
 #define        HIFN_D_DST_RSIZE                80*4
 #define        HIFN_D_RES_RSIZE                24*4
 
+#define HIFN_D_DST_DALIGN              4
+
 #define HIFN_QUEUE_LENGTH              HIFN_D_CMD_RSIZE-5
 
 #define AES_MIN_KEY_SIZE               16
@@ -392,8 +394,8 @@ static atomic_t hifn_dev_number;
 
 struct hifn_desc
 {
-       volatile u32            l;
-       volatile u32            p;
+       volatile __le32         l;
+       volatile __le32         p;
 };
 
 struct hifn_dma {
@@ -463,7 +465,7 @@ struct hifn_device
 
        unsigned int            pk_clk_freq;
 
-#ifdef CRYPTO_DEV_HIFN_795X_RNG
+#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
        unsigned int            rng_wait_time;
        ktime_t                 rngtime;
        struct hwrng            rng;
@@ -481,10 +483,10 @@ struct hifn_device
 
 struct hifn_base_command
 {
-       volatile u16            masks;
-       volatile u16            session_num;
-       volatile u16            total_source_count;
-       volatile u16            total_dest_count;
+       volatile __le16         masks;
+       volatile __le16         session_num;
+       volatile __le16         total_source_count;
+       volatile __le16         total_dest_count;
 };
 
 #define        HIFN_BASE_CMD_COMP              0x0100  /* enable compression engine */
@@ -504,10 +506,10 @@ struct hifn_base_command
  */
 struct hifn_crypt_command
 {
-       volatile u16            masks;
-       volatile u16            header_skip;
-       volatile u16            source_count;
-       volatile u16            reserved;
+       volatile __le16                 masks;
+       volatile __le16                 header_skip;
+       volatile __le16                 source_count;
+       volatile __le16                 reserved;
 };
 
 #define        HIFN_CRYPT_CMD_ALG_MASK         0x0003          /* algorithm: */
@@ -535,10 +537,10 @@ struct hifn_crypt_command
  */
 struct hifn_mac_command
 {
-       volatile u16            masks;
-       volatile u16            header_skip;
-       volatile u16            source_count;
-       volatile u16            reserved;
+       volatile __le16         masks;
+       volatile __le16         header_skip;
+       volatile __le16         source_count;
+       volatile __le16         reserved;
 };
 
 #define        HIFN_MAC_CMD_ALG_MASK           0x0001
@@ -564,10 +566,10 @@ struct hifn_mac_command
 
 struct hifn_comp_command
 {
-       volatile u16            masks;
-       volatile u16            header_skip;
-       volatile u16            source_count;
-       volatile u16            reserved;
+       volatile __le16         masks;
+       volatile __le16         header_skip;
+       volatile __le16         source_count;
+       volatile __le16         reserved;
 };
 
 #define        HIFN_COMP_CMD_SRCLEN_M          0xc000
@@ -583,10 +585,10 @@ struct hifn_comp_command
 
 struct hifn_base_result
 {
-       volatile u16            flags;
-       volatile u16            session;
-       volatile u16            src_cnt;                /* 15:0 of source count */
-       volatile u16            dst_cnt;                /* 15:0 of dest count */
+       volatile __le16         flags;
+       volatile __le16         session;
+       volatile __le16         src_cnt;                /* 15:0 of source count */
+       volatile __le16         dst_cnt;                /* 15:0 of dest count */
 };
 
 #define        HIFN_BASE_RES_DSTOVERRUN        0x0200  /* destination overrun */
@@ -597,8 +599,8 @@ struct hifn_base_result
 
 struct hifn_comp_result
 {
-       volatile u16            flags;
-       volatile u16            crc;
+       volatile __le16         flags;
+       volatile __le16         crc;
 };
 
 #define        HIFN_COMP_RES_LCB_M             0xff00  /* longitudinal check byte */
@@ -609,8 +611,8 @@ struct hifn_comp_result
 
 struct hifn_mac_result
 {
-       volatile u16            flags;
-       volatile u16            reserved;
+       volatile __le16         flags;
+       volatile __le16         reserved;
        /* followed by 0, 6, 8, or 10 u16's of the MAC, then crypt */
 };
 
@@ -619,8 +621,8 @@ struct hifn_mac_result
 
 struct hifn_crypt_result
 {
-       volatile u16            flags;
-       volatile u16            reserved;
+       volatile __le16         flags;
+       volatile __le16         reserved;
 };
 
 #define        HIFN_CRYPT_RES_SRC_NOTZERO      0x0001  /* source expired */
@@ -670,7 +672,7 @@ static inline u32 hifn_read_0(struct hifn_device *dev, u32 reg)
 {
        u32 ret;
 
-       ret = readl((char *)(dev->bar[0]) + reg);
+       ret = readl(dev->bar[0] + reg);
 
        return ret;
 }
@@ -679,19 +681,19 @@ static inline u32 hifn_read_1(struct hifn_device *dev, u32 reg)
 {
        u32 ret;
 
-       ret = readl((char *)(dev->bar[1]) + reg);
+       ret = readl(dev->bar[1] + reg);
 
        return ret;
 }
 
 static inline void hifn_write_0(struct hifn_device *dev, u32 reg, u32 val)
 {
-       writel(val, (char *)(dev->bar[0]) + reg);
+       writel((__force u32)cpu_to_le32(val), dev->bar[0] + reg);
 }
 
 static inline void hifn_write_1(struct hifn_device *dev, u32 reg, u32 val)
 {
-       writel(val, (char *)(dev->bar[1]) + reg);
+       writel((__force u32)cpu_to_le32(val), dev->bar[1] + reg);
 }
 
 static void hifn_wait_puc(struct hifn_device *dev)
@@ -795,7 +797,7 @@ static struct pci2id {
        }
 };
 
-#ifdef CRYPTO_DEV_HIFN_795X_RNG
+#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
 static int hifn_rng_data_present(struct hwrng *rng, int wait)
 {
        struct hifn_device *dev = (struct hifn_device *)rng->priv;
@@ -880,7 +882,7 @@ static int hifn_init_pubrng(struct hifn_device *dev)
        dprintk("Chip %s: RNG engine has been successfully initialised.\n",
                        dev->name);
 
-#ifdef CRYPTO_DEV_HIFN_795X_RNG
+#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
        /* First value must be discarded */
        hifn_read_1(dev, HIFN_1_RNG_DATA);
        dev->rngtime = ktime_get();
@@ -1037,14 +1039,14 @@ static void hifn_init_registers(struct hifn_device *dev)
        hifn_write_0(dev, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
 
        /* write all 4 ring address registers */
-       hifn_write_1(dev, HIFN_1_DMA_CRAR, __cpu_to_le32(dptr +
-                               offsetof(struct hifn_dma, cmdr[0])));
-       hifn_write_1(dev, HIFN_1_DMA_SRAR, __cpu_to_le32(dptr +
-                               offsetof(struct hifn_dma, srcr[0])));
-       hifn_write_1(dev, HIFN_1_DMA_DRAR, __cpu_to_le32(dptr +
-                               offsetof(struct hifn_dma, dstr[0])));
-       hifn_write_1(dev, HIFN_1_DMA_RRAR, __cpu_to_le32(dptr +
-                               offsetof(struct hifn_dma, resr[0])));
+       hifn_write_1(dev, HIFN_1_DMA_CRAR, dptr +
+                               offsetof(struct hifn_dma, cmdr[0]));
+       hifn_write_1(dev, HIFN_1_DMA_SRAR, dptr +
+                               offsetof(struct hifn_dma, srcr[0]));
+       hifn_write_1(dev, HIFN_1_DMA_DRAR, dptr +
+                               offsetof(struct hifn_dma, dstr[0]));
+       hifn_write_1(dev, HIFN_1_DMA_RRAR, dptr +
+                               offsetof(struct hifn_dma, resr[0]));
 
        mdelay(2);
 #if 0
@@ -1178,8 +1180,8 @@ static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page,
        idx = dma->srci;
 
        dma->srcr[idx].p = __cpu_to_le32(addr);
-       dma->srcr[idx].l = __cpu_to_le32(size) | HIFN_D_VALID |
-                       HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST;
+       dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID |
+                       HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST);
 
        if (++idx == HIFN_D_SRC_RSIZE) {
                dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID |
@@ -1458,10 +1460,6 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
 static int ablkcipher_walk(struct ablkcipher_request *req,
                struct ablkcipher_walk *w)
 {
-       unsigned blocksize =
-               crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
-       unsigned alignmask =
-               crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
        struct scatterlist *src, *dst, *t;
        void *daddr;
        unsigned int nbytes = req->nbytes, offset, copy, diff;
@@ -1477,15 +1475,13 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
                dst = &req->dst[idx];
 
                dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, "
-                               "blocksize: %u, nbytes: %u.\n",
+                               "nbytes: %u.\n",
                                __func__, src->length, dst->length, src->offset,
-                               dst->offset, offset, blocksize, nbytes);
+                               dst->offset, offset, nbytes);
 
-               if (src->length & (blocksize - 1) ||
-                               src->offset & (alignmask - 1) ||
-                               dst->length & (blocksize - 1) ||
-                               dst->offset & (alignmask - 1) ||
-                               offset) {
+               if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
+                   !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
+                   offset) {
                        unsigned slen = src->length - offset;
                        unsigned dlen = PAGE_SIZE;
 
@@ -1498,8 +1494,8 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 
                        idx += err;
 
-                       copy = slen & ~(blocksize - 1);
-                       diff = slen & (blocksize - 1);
+                       copy = slen & ~(HIFN_D_DST_DALIGN - 1);
+                       diff = slen & (HIFN_D_DST_DALIGN - 1);
 
                        if (dlen < nbytes) {
                                /*
@@ -1507,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
                                 * to put there additional blocksized chunk,
                                 * so we mark that page as containing only
                                 * blocksize aligned chunks:
-                                *      t->length = (slen & ~(blocksize - 1));
+                                *      t->length = (slen & ~(HIFN_D_DST_DALIGN - 1));
                                 * and increase number of bytes to be processed
                                 * in next chunk:
                                 *      nbytes += diff;
@@ -1567,10 +1563,6 @@ static int hifn_setup_session(struct ablkcipher_request *req)
        unsigned int nbytes = req->nbytes, idx = 0, len;
        int err = -EINVAL, sg_num;
        struct scatterlist *src, *dst, *t;
-       unsigned blocksize =
-               crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
-       unsigned alignmask =
-               crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
 
        if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB)
                goto err_out_exit;
@@ -1578,17 +1570,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
        ctx->walk.flags = 0;
 
        while (nbytes) {
-               src = &req->src[idx];
                dst = &req->dst[idx];
 
-               if (src->length & (blocksize - 1) ||
-                               src->offset & (alignmask - 1) ||
-                               dst->length & (blocksize - 1) ||
-                               dst->offset & (alignmask - 1)) {
+               if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
+                   !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN))
                        ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
-               }
 
-               nbytes -= src->length;
+               nbytes -= dst->length;
                idx++;
        }
 
@@ -1602,7 +1590,10 @@ static int hifn_setup_session(struct ablkcipher_request *req)
        idx = 0;
 
        sg_num = ablkcipher_walk(req, &ctx->walk);
-
+       if (sg_num < 0) {
+               err = sg_num;
+               goto err_out_exit;
+       }
        atomic_set(&ctx->sg_num, sg_num);
 
        spin_lock_irqsave(&dev->lock, flags);
@@ -1651,7 +1642,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 err_out:
        spin_unlock_irqrestore(&dev->lock, flags);
 err_out_exit:
-       if (err && printk_ratelimit())
+       if (err)
                dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, "
                                "type: %u, err: %d.\n",
                        dev->name, ctx->iv, ctx->ivsize,
@@ -2202,9 +2193,9 @@ static int hifn_setup_crypto(struct ablkcipher_request *req, u8 op,
                return err;
 
        if (dev->started < HIFN_QUEUE_LENGTH && dev->queue.qlen)
-               err = hifn_process_queue(dev);
+               hifn_process_queue(dev);
 
-       return err;
+       return -EINPROGRESS;
 }
 
 /*
@@ -2520,9 +2511,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
        alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
        alg->alg.cra_blocksize = t->bsize;
        alg->alg.cra_ctxsize = sizeof(struct hifn_context);
-       alg->alg.cra_alignmask = 15;
-       if (t->bsize == 8)
-               alg->alg.cra_alignmask = 3;
+       alg->alg.cra_alignmask = 0;
        alg->alg.cra_type = &crypto_ablkcipher_type;
        alg->alg.cra_module = THIS_MODULE;
        alg->alg.cra_u.ablkcipher = t->ablkcipher;