aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-11-24 08:59:25 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-12-24 19:01:51 -0500
commit75741a034024f146ba5431602f3ad33a5df8363c (patch)
treedff26a78946ac5c51f445f17cef3d69235ba04a9 /drivers/crypto
parent09fbf7c0f24176ef3b450c590f220ed8033dd2c3 (diff)
crypto: hifn_795x - Fix DMA setup
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/hifn_795x.c165
1 files changed, 81 insertions, 84 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 2969ea99f7c7..27b8af983aae 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -662,7 +662,6 @@ struct hifn_context
662 unsigned int keysize, ivsize; 662 unsigned int keysize, ivsize;
663 u8 op, type, mode, unused; 663 u8 op, type, mode, unused;
664 struct ablkcipher_walk walk; 664 struct ablkcipher_walk walk;
665 atomic_t sg_num;
666}; 665};
667 666
668#define crypto_alg_to_hifn(a) container_of(a, struct hifn_crypto_alg, alg) 667#define crypto_alg_to_hifn(a) container_of(a, struct hifn_crypto_alg, alg)
@@ -1284,7 +1283,7 @@ err_out:
1284} 1283}
1285 1284
1286static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, 1285static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page,
1287 unsigned int offset, unsigned int size) 1286 unsigned int offset, unsigned int size, int last)
1288{ 1287{
1289 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1288 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1290 int idx; 1289 int idx;
@@ -1296,12 +1295,12 @@ static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page,
1296 1295
1297 dma->srcr[idx].p = __cpu_to_le32(addr); 1296 dma->srcr[idx].p = __cpu_to_le32(addr);
1298 dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | 1297 dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID |
1299 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1298 HIFN_D_MASKDONEIRQ | (last ? HIFN_D_LAST : 0));
1300 1299
1301 if (++idx == HIFN_D_SRC_RSIZE) { 1300 if (++idx == HIFN_D_SRC_RSIZE) {
1302 dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | 1301 dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID |
1303 HIFN_D_JUMP | 1302 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ |
1304 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1303 (last ? HIFN_D_LAST : 0));
1305 idx = 0; 1304 idx = 0;
1306 } 1305 }
1307 1306
@@ -1342,7 +1341,7 @@ static void hifn_setup_res_desc(struct hifn_device *dev)
1342} 1341}
1343 1342
1344static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page, 1343static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1345 unsigned offset, unsigned size) 1344 unsigned offset, unsigned size, int last)
1346{ 1345{
1347 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1346 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1348 int idx; 1347 int idx;
@@ -1353,12 +1352,12 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1353 idx = dma->dsti; 1352 idx = dma->dsti;
1354 dma->dstr[idx].p = __cpu_to_le32(addr); 1353 dma->dstr[idx].p = __cpu_to_le32(addr);
1355 dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | 1354 dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID |
1356 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1355 HIFN_D_MASKDONEIRQ | (last ? HIFN_D_LAST : 0));
1357 1356
1358 if (++idx == HIFN_D_DST_RSIZE) { 1357 if (++idx == HIFN_D_DST_RSIZE) {
1359 dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID | 1358 dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID |
1360 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | 1359 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ |
1361 HIFN_D_LAST); 1360 (last ? HIFN_D_LAST : 0));
1362 idx = 0; 1361 idx = 0;
1363 } 1362 }
1364 dma->dsti = idx; 1363 dma->dsti = idx;
@@ -1370,16 +1369,47 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1370 } 1369 }
1371} 1370}
1372 1371
1373static int hifn_setup_dma(struct hifn_device *dev, struct page *spage, unsigned int soff, 1372static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
1374 struct page *dpage, unsigned int doff, unsigned int nbytes, void *priv, 1373 struct scatterlist *src, struct scatterlist *dst,
1375 struct hifn_context *ctx) 1374 unsigned int nbytes, void *priv)
1376{ 1375{
1377 dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, nbytes: %u, priv: %p, ctx: %p.\n", 1376 struct scatterlist *t;
1377 struct page *spage, *dpage;
1378 unsigned int soff, doff;
1379 unsigned int n, len;
1380
1381 t = &ctx->walk.cache[0];
1382 n = nbytes;
1383 while (n) {
1384 if (t->length) {
1385 spage = dpage = sg_page(t);
1386 soff = doff = 0;
1387 len = t->length;
1388 } else {
1389 spage = sg_page(src);
1390 soff = src->offset;
1391
1392 dpage = sg_page(dst);
1393 doff = dst->offset;
1394
1395 len = dst->length;
1396 }
1397 len = min(len, n);
1398
1399 dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, "
1400 "nbytes: %u, priv: %p, ctx: %p.\n",
1378 dev->name, spage, soff, dpage, doff, nbytes, priv, ctx); 1401 dev->name, spage, soff, dpage, doff, nbytes, priv, ctx);
1379 1402
1380 hifn_setup_src_desc(dev, spage, soff, nbytes); 1403 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
1404 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
1405
1406 src++;
1407 dst++;
1408 t++;
1409 n -= len;
1410 }
1411
1381 hifn_setup_cmd_desc(dev, ctx, priv, nbytes); 1412 hifn_setup_cmd_desc(dev, ctx, priv, nbytes);
1382 hifn_setup_dst_desc(dev, dpage, doff, nbytes);
1383 hifn_setup_res_desc(dev); 1413 hifn_setup_res_desc(dev);
1384 return 0; 1414 return 0;
1385} 1415}
@@ -1560,11 +1590,10 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1560{ 1590{
1561 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1591 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
1562 struct hifn_device *dev = ctx->dev; 1592 struct hifn_device *dev = ctx->dev;
1563 struct page *spage, *dpage; 1593 unsigned long dlen, flags;
1564 unsigned long soff, doff, dlen, flags; 1594 unsigned int nbytes = req->nbytes, idx = 0;
1565 unsigned int nbytes = req->nbytes, idx = 0, len;
1566 int err = -EINVAL, sg_num; 1595 int err = -EINVAL, sg_num;
1567 struct scatterlist *src, *dst, *t; 1596 struct scatterlist *dst;
1568 1597
1569 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) 1598 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB)
1570 goto err_out_exit; 1599 goto err_out_exit;
@@ -1589,15 +1618,11 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1589 return err; 1618 return err;
1590 } 1619 }
1591 1620
1592 nbytes = req->nbytes;
1593 idx = 0;
1594
1595 sg_num = ablkcipher_walk(req, &ctx->walk); 1621 sg_num = ablkcipher_walk(req, &ctx->walk);
1596 if (sg_num < 0) { 1622 if (sg_num < 0) {
1597 err = sg_num; 1623 err = sg_num;
1598 goto err_out_exit; 1624 goto err_out_exit;
1599 } 1625 }
1600 atomic_set(&ctx->sg_num, sg_num);
1601 1626
1602 spin_lock_irqsave(&dev->lock, flags); 1627 spin_lock_irqsave(&dev->lock, flags);
1603 if (dev->started + sg_num > HIFN_QUEUE_LENGTH) { 1628 if (dev->started + sg_num > HIFN_QUEUE_LENGTH) {
@@ -1606,36 +1631,11 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1606 } 1631 }
1607 1632
1608 dev->snum++; 1633 dev->snum++;
1609 dev->started += sg_num; 1634 dev->started++;
1610
1611 while (nbytes) {
1612 src = &req->src[idx];
1613 dst = &req->dst[idx];
1614 t = &ctx->walk.cache[idx];
1615
1616 if (t->length) {
1617 spage = dpage = sg_page(t);
1618 soff = doff = 0;
1619 len = t->length;
1620 } else {
1621 spage = sg_page(src);
1622 soff = src->offset;
1623
1624 dpage = sg_page(dst);
1625 doff = dst->offset;
1626
1627 len = dst->length;
1628 }
1629
1630 idx++;
1631 1635
1632 err = hifn_setup_dma(dev, spage, soff, dpage, doff, nbytes, 1636 err = hifn_setup_dma(dev, ctx, req->src, req->dst, req->nbytes, req);
1633 req, ctx); 1637 if (err)
1634 if (err) 1638 goto err_out;
1635 goto err_out;
1636
1637 nbytes -= min(len, nbytes);
1638 }
1639 1639
1640 dev->active = HIFN_DEFAULT_ACTIVE_NUM; 1640 dev->active = HIFN_DEFAULT_ACTIVE_NUM;
1641 spin_unlock_irqrestore(&dev->lock, flags); 1641 spin_unlock_irqrestore(&dev->lock, flags);
@@ -1665,6 +1665,7 @@ static int hifn_test(struct hifn_device *dev, int encdec, u8 snum)
1665 0xEF, 0x8A, 0x2C, 0x3B, 1665 0xEF, 0x8A, 0x2C, 0x3B,
1666 0x88, 0x4C, 0xFA, 0x59, 1666 0x88, 0x4C, 0xFA, 0x59,
1667 0xCA, 0x34, 0x2B, 0x2E}; 1667 0xCA, 0x34, 0x2B, 0x2E};
1668 struct scatterlist sg;
1668 1669
1669 memset(src, 0, sizeof(src)); 1670 memset(src, 0, sizeof(src));
1670 memset(ctx.key, 0, sizeof(ctx.key)); 1671 memset(ctx.key, 0, sizeof(ctx.key));
@@ -1676,12 +1677,11 @@ static int hifn_test(struct hifn_device *dev, int encdec, u8 snum)
1676 ctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT; 1677 ctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT;
1677 ctx.mode = ACRYPTO_MODE_ECB; 1678 ctx.mode = ACRYPTO_MODE_ECB;
1678 ctx.type = ACRYPTO_TYPE_AES_128; 1679 ctx.type = ACRYPTO_TYPE_AES_128;
1679 atomic_set(&ctx.sg_num, 1); 1680 ctx.walk.cache[0].length = 0;
1680 1681
1681 err = hifn_setup_dma(dev, 1682 sg_init_one(&sg, &src, sizeof(src));
1682 virt_to_page(src), offset_in_page(src), 1683
1683 virt_to_page(src), offset_in_page(src), 1684 err = hifn_setup_dma(dev, &ctx, &sg, &sg, sizeof(src), NULL);
1684 sizeof(src), NULL, &ctx);
1685 if (err) 1685 if (err)
1686 goto err_out; 1686 goto err_out;
1687 1687
@@ -1772,53 +1772,50 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
1772 dprintk("%s: req: %p, ctx: %p.\n", __func__, req, ctx); 1772 dprintk("%s: req: %p, ctx: %p.\n", __func__, req, ctx);
1773 1773
1774 dev = ctx->dev; 1774 dev = ctx->dev;
1775 dprintk("%s: req: %p, started: %d, sg_num: %d.\n", 1775 dprintk("%s: req: %p, started: %d.\n", __func__, req, dev->started);
1776 __func__, req, dev->started, atomic_read(&ctx->sg_num));
1777 1776
1778 if (--dev->started < 0) 1777 if (--dev->started < 0)
1779 BUG(); 1778 BUG();
1780 1779
1781 if (atomic_dec_and_test(&ctx->sg_num)) { 1780 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1782 unsigned int nbytes = req->nbytes; 1781 unsigned int nbytes = req->nbytes;
1783 int idx = 0, err; 1782 int idx = 0, err;
1784 struct scatterlist *dst, *t; 1783 struct scatterlist *dst, *t;
1785 void *saddr; 1784 void *saddr;
1786 1785
1787 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { 1786 while (nbytes) {
1788 while (nbytes) { 1787 t = &ctx->walk.cache[idx];
1789 t = &ctx->walk.cache[idx]; 1788 dst = &req->dst[idx];
1790 dst = &req->dst[idx];
1791 1789
1792 dprintk("\n%s: sg_page(t): %p, t->length: %u, " 1790 dprintk("\n%s: sg_page(t): %p, t->length: %u, "
1793 "sg_page(dst): %p, dst->length: %u, " 1791 "sg_page(dst): %p, dst->length: %u, "
1794 "nbytes: %u.\n", 1792 "nbytes: %u.\n",
1795 __func__, sg_page(t), t->length, 1793 __func__, sg_page(t), t->length,
1796 sg_page(dst), dst->length, nbytes); 1794 sg_page(dst), dst->length, nbytes);
1797
1798 if (!t->length) {
1799 nbytes -= min(dst->length, nbytes);
1800 idx++;
1801 continue;
1802 }
1803 1795
1804 saddr = kmap_atomic(sg_page(t), KM_IRQ1); 1796 if (!t->length) {
1797 nbytes -= min(dst->length, nbytes);
1798 idx++;
1799 continue;
1800 }
1805 1801
1806 err = ablkcipher_get(saddr, &t->length, t->offset, 1802 saddr = kmap_atomic(sg_page(t), KM_IRQ1);
1807 dst, nbytes, &nbytes);
1808 if (err < 0) {
1809 kunmap_atomic(saddr, KM_IRQ1);
1810 break;
1811 }
1812 1803
1813 idx += err; 1804 err = ablkcipher_get(saddr, &t->length, t->offset,
1805 dst, nbytes, &nbytes);
1806 if (err < 0) {
1814 kunmap_atomic(saddr, KM_IRQ1); 1807 kunmap_atomic(saddr, KM_IRQ1);
1808 break;
1815 } 1809 }
1816 1810
1817 ablkcipher_walk_exit(&ctx->walk); 1811 idx += err;
1812 kunmap_atomic(saddr, KM_IRQ1);
1818 } 1813 }
1819 1814
1820 req->base.complete(&req->base, error); 1815 ablkcipher_walk_exit(&ctx->walk);
1821 } 1816 }
1817
1818 req->base.complete(&req->base, error);
1822} 1819}
1823 1820
1824static void hifn_check_for_completion(struct hifn_device *dev, int error) 1821static void hifn_check_for_completion(struct hifn_device *dev, int error)