diff options
Diffstat (limited to 'drivers/crypto/omap-sham.c')
-rw-r--r-- | drivers/crypto/omap-sham.c | 106 |
1 files changed, 99 insertions, 7 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 86b89ace836f..ad02aa63b519 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -229,6 +229,7 @@ struct omap_sham_dev { u8 xmit_buf[BUFLEN] OMAP_ALIGNED; unsigned long flags; + int fallback_sz; struct crypto_queue queue; struct ahash_request *req; @@ -759,6 +760,13 @@ static int omap_sham_align_sgs(struct scatterlist *sg, while (nbytes > 0 && sg_tmp) { n++; +#ifdef CONFIG_ZONE_DMA + if (page_zonenum(sg_page(sg_tmp)) != ZONE_DMA) { + aligned = false; + break; + } +#endif + if (offset < sg_tmp->length) { if (!IS_ALIGNED(offset + sg_tmp->offset, 4)) { aligned = false; @@ -809,9 +817,6 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update) bool final = rctx->flags & BIT(FLAGS_FINUP); int xmit_len, hash_later; - if (!req) - return 0; - bs = get_block_size(rctx); if (update) @@ -1002,7 +1007,7 @@ static int omap_sham_update_req(struct omap_sham_dev *dd) ctx->total, ctx->digcnt, (ctx->flags & BIT(FLAGS_FINUP)) != 0); if (ctx->total < get_block_size(ctx) || - ctx->total < OMAP_SHA_DMA_THRESHOLD) + ctx->total < dd->fallback_sz) ctx->flags |= BIT(FLAGS_CPU); if (ctx->flags & BIT(FLAGS_CPU)) @@ -1258,11 +1263,11 @@ static int omap_sham_final(struct ahash_request *req) /* * OMAP HW accel works only with buffers >= 9. * HMAC is always >= 9 because ipad == block size. - * If buffersize is less than DMA_THRESHOLD, we use fallback + * If buffersize is less than fallback_sz, we use fallback * SW encoding, as using DMA + HW in this case doesn't provide * any benefit. */ - if (!ctx->digcnt && ctx->bufcnt < OMAP_SHA_DMA_THRESHOLD) + if (!ctx->digcnt && ctx->bufcnt < ctx->dd->fallback_sz) return omap_sham_final_shash(req); else if (ctx->bufcnt) return omap_sham_enqueue(req, OP_FINAL); @@ -1761,7 +1766,7 @@ static void omap_sham_done_task(unsigned long data) if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) { /* hash or semi-hash ready */ clear_bit(FLAGS_DMA_READY, &dd->flags); - goto finish; + goto finish; } } @@ -2013,6 +2018,85 @@ err: return err; } +static ssize_t fallback_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct omap_sham_dev *dd = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", dd->fallback_sz); +} + +static ssize_t fallback_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct omap_sham_dev *dd = dev_get_drvdata(dev); + ssize_t status; + long value; + + status = kstrtol(buf, 0, &value); + if (status) + return status; + + /* HW accelerator only works with buffers > 9 */ + if (value < 9) { + dev_err(dev, "minimum fallback size 9\n"); + return -EINVAL; + } + + dd->fallback_sz = value; + + return size; +} + +static ssize_t queue_len_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct omap_sham_dev *dd = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", dd->queue.max_qlen); +} + +static ssize_t queue_len_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + struct omap_sham_dev *dd = dev_get_drvdata(dev); + ssize_t status; + long value; + unsigned long flags; + + status = kstrtol(buf, 0, &value); + if (status) + return status; + + if (value < 1) + return -EINVAL; + + /* + * Changing the queue size in fly is safe, if size becomes smaller + * than current size, it will just not accept new entries until + * it has shrank enough. + */ + spin_lock_irqsave(&dd->lock, flags); + dd->queue.max_qlen = value; + spin_unlock_irqrestore(&dd->lock, flags); + + return size; +} + +static DEVICE_ATTR_RW(queue_len); +static DEVICE_ATTR_RW(fallback); + +static struct attribute *omap_sham_attrs[] = { + &dev_attr_queue_len.attr, + &dev_attr_fallback.attr, + NULL, +}; + +static struct attribute_group omap_sham_attr_group = { + .attrs = omap_sham_attrs, +}; + static int omap_sham_probe(struct platform_device *pdev) { struct omap_sham_dev *dd; @@ -2074,6 +2158,8 @@ static int omap_sham_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY); + dd->fallback_sz = OMAP_SHA_DMA_THRESHOLD; + pm_runtime_enable(dev); pm_runtime_irq_safe(dev); @@ -2111,6 +2197,12 @@ static int omap_sham_probe(struct platform_device *pdev) } } + err = sysfs_create_group(&dev->kobj, &omap_sham_attr_group); + if (err) { + dev_err(dev, "could not create sysfs device attrs\n"); + goto err_algs; + } + return 0; err_algs: |