diff options
Diffstat (limited to 'drivers/crypto/talitos.c')
| -rw-r--r-- | drivers/crypto/talitos.c | 132 | 
1 files changed, 66 insertions, 66 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 661dc3eb1d6..624b8be0c36 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -32,6 +32,8 @@  #include <linux/interrupt.h>  #include <linux/crypto.h>  #include <linux/hw_random.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/dma-mapping.h>  #include <linux/io.h> @@ -336,20 +338,29 @@ DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE)  static u32 current_desc_hdr(struct device *dev, int ch)  {  	struct talitos_private *priv = dev_get_drvdata(dev); -	int tail = priv->chan[ch].tail; +	int tail, iter;  	dma_addr_t cur_desc; -	cur_desc = in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); +	cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32; +	cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); -	while (priv->chan[ch].fifo[tail].dma_desc != cur_desc) { -		tail = (tail + 1) & (priv->fifo_len - 1); -		if (tail == priv->chan[ch].tail) { +	if (!cur_desc) { +		dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n"); +		return 0; +	} + +	tail = priv->chan[ch].tail; + +	iter = tail; +	while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) { +		iter = (iter + 1) & (priv->fifo_len - 1); +		if (iter == tail) {  			dev_err(dev, "couldn't locate current descriptor\n");  			return 0;  		}  	} -	return priv->chan[ch].fifo[tail].desc->hdr; +	return priv->chan[ch].fifo[iter].desc->hdr;  }  /* @@ -671,39 +682,20 @@ static int aead_setkey(struct crypto_aead *authenc,  		       const u8 *key, unsigned int keylen)  {  	struct talitos_ctx *ctx = crypto_aead_ctx(authenc); -	struct rtattr *rta = (void *)key; -	struct crypto_authenc_key_param *param; -	unsigned int authkeylen; -	unsigned int enckeylen; - -	if (!RTA_OK(rta, keylen)) -		goto badkey; - -	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) -		goto badkey; +	struct crypto_authenc_keys keys; -	if (RTA_PAYLOAD(rta) < sizeof(*param)) +	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)  		goto badkey; -	param = RTA_DATA(rta); -	enckeylen = be32_to_cpu(param->enckeylen); - -	key += RTA_ALIGN(rta->rta_len); -	keylen -= RTA_ALIGN(rta->rta_len); - -	if (keylen < enckeylen) +	if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)  		goto badkey; -	authkeylen = keylen - enckeylen; - -	if (keylen > TALITOS_MAX_KEY_SIZE) -		goto badkey; +	memcpy(ctx->key, keys.authkey, keys.authkeylen); +	memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen); -	memcpy(&ctx->key, key, keylen); - -	ctx->keylen = keylen; -	ctx->enckeylen = enckeylen; -	ctx->authkeylen = authkeylen; +	ctx->keylen = keys.authkeylen + keys.enckeylen; +	ctx->enckeylen = keys.enckeylen; +	ctx->authkeylen = keys.authkeylen;  	return 0; @@ -807,7 +799,7 @@ static void ipsec_esp_unmap(struct device *dev,  	if (edesc->assoc_chained)  		talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE); -	else +	else if (areq->assoclen)  		/* assoc_nents counts also for IV in non-contiguous cases */  		dma_unmap_sg(dev, areq->assoc,  			     edesc->assoc_nents ? edesc->assoc_nents - 1 : 1, @@ -990,7 +982,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,  		dma_sync_single_for_device(dev, edesc->dma_link_tbl,  					   edesc->dma_len, DMA_BIDIRECTIONAL);  	} else { -		to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc)); +		if (areq->assoclen) +			to_talitos_ptr(&desc->ptr[1], +				       sg_dma_address(areq->assoc)); +		else +			to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);  		desc->ptr[1].j_extent = 0;  	} @@ -1125,7 +1121,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,  						 unsigned int authsize,  						 unsigned int ivsize,  						 int icv_stashing, -						 u32 cryptoflags) +						 u32 cryptoflags, +						 bool encrypt)  {  	struct talitos_edesc *edesc;  	int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len; @@ -1139,10 +1136,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,  		return ERR_PTR(-EINVAL);  	} -	if (iv) +	if (ivsize)  		iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); -	if (assoc) { +	if (assoclen) {  		/*  		 * Currently it is assumed that iv is provided whenever assoc  		 * is. @@ -1158,19 +1155,17 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,  			assoc_nents = assoc_nents ? assoc_nents + 1 : 2;  	} -	src_nents = sg_count(src, cryptlen + authsize, &src_chained); -	src_nents = (src_nents == 1) ? 0 : src_nents; - -	if (!dst) { -		dst_nents = 0; -	} else { -		if (dst == src) { -			dst_nents = src_nents; -		} else { -			dst_nents = sg_count(dst, cryptlen + authsize, -					     &dst_chained); -			dst_nents = (dst_nents == 1) ? 0 : dst_nents; -		} +	if (!dst || dst == src) { +		src_nents = sg_count(src, cryptlen + authsize, &src_chained); +		src_nents = (src_nents == 1) ? 0 : src_nents; +		dst_nents = dst ? src_nents : 0; +	} else { /* dst && dst != src*/ +		src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize), +				     &src_chained); +		src_nents = (src_nents == 1) ? 0 : src_nents; +		dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0), +				     &dst_chained); +		dst_nents = (dst_nents == 1) ? 0 : dst_nents;  	}  	/* @@ -1190,9 +1185,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,  	edesc = kmalloc(alloc_len, GFP_DMA | flags);  	if (!edesc) { -		talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); +		if (assoc_chained) +			talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); +		else if (assoclen) +			dma_unmap_sg(dev, assoc, +				     assoc_nents ? assoc_nents - 1 : 1, +				     DMA_TO_DEVICE); +  		if (iv_dma)  			dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE); +  		dev_err(dev, "could not allocate edescriptor\n");  		return ERR_PTR(-ENOMEM);  	} @@ -1214,7 +1216,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,  }  static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, -					      int icv_stashing) +					      int icv_stashing, bool encrypt)  {  	struct crypto_aead *authenc = crypto_aead_reqtfm(areq);  	struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -1223,7 +1225,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,  	return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,  				   iv, areq->assoclen, areq->cryptlen,  				   ctx->authsize, ivsize, icv_stashing, -				   areq->base.flags); +				   areq->base.flags, encrypt);  }  static int aead_encrypt(struct aead_request *req) @@ -1233,7 +1235,7 @@ static int aead_encrypt(struct aead_request *req)  	struct talitos_edesc *edesc;  	/* allocate extended descriptor */ -	edesc = aead_edesc_alloc(req, req->iv, 0); +	edesc = aead_edesc_alloc(req, req->iv, 0, true);  	if (IS_ERR(edesc))  		return PTR_ERR(edesc); @@ -1256,7 +1258,7 @@ static int aead_decrypt(struct aead_request *req)  	req->cryptlen -= authsize;  	/* allocate extended descriptor */ -	edesc = aead_edesc_alloc(req, req->iv, 1); +	edesc = aead_edesc_alloc(req, req->iv, 1, false);  	if (IS_ERR(edesc))  		return PTR_ERR(edesc); @@ -1302,7 +1304,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)  	struct talitos_edesc *edesc;  	/* allocate extended descriptor */ -	edesc = aead_edesc_alloc(areq, req->giv, 0); +	edesc = aead_edesc_alloc(areq, req->giv, 0, true);  	if (IS_ERR(edesc))  		return PTR_ERR(edesc); @@ -1458,7 +1460,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,  }  static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * -						    areq) +						    areq, bool encrypt)  {  	struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);  	struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); @@ -1466,7 +1468,7 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *  	return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,  				   areq->info, 0, areq->nbytes, 0, ivsize, 0, -				   areq->base.flags); +				   areq->base.flags, encrypt);  }  static int ablkcipher_encrypt(struct ablkcipher_request *areq) @@ -1476,7 +1478,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)  	struct talitos_edesc *edesc;  	/* allocate extended descriptor */ -	edesc = ablkcipher_edesc_alloc(areq); +	edesc = ablkcipher_edesc_alloc(areq, true);  	if (IS_ERR(edesc))  		return PTR_ERR(edesc); @@ -1493,7 +1495,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)  	struct talitos_edesc *edesc;  	/* allocate extended descriptor */ -	edesc = ablkcipher_edesc_alloc(areq); +	edesc = ablkcipher_edesc_alloc(areq, false);  	if (IS_ERR(edesc))  		return PTR_ERR(edesc); @@ -1645,7 +1647,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,  	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);  	return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0, -				   nbytes, 0, 0, 0, areq->base.flags); +				   nbytes, 0, 0, 0, areq->base.flags, false);  }  static int ahash_init(struct ahash_request *areq) @@ -2493,8 +2495,6 @@ static int talitos_remove(struct platform_device *ofdev)  	iounmap(priv->reg); -	dev_set_drvdata(dev, NULL); -  	kfree(priv);  	return 0; @@ -2637,6 +2637,8 @@ static int talitos_probe(struct platform_device *ofdev)  	if (!priv)  		return -ENOMEM; +	INIT_LIST_HEAD(&priv->alg_list); +  	dev_set_drvdata(dev, priv);  	priv->ofdev = ofdev; @@ -2657,8 +2659,6 @@ static int talitos_probe(struct platform_device *ofdev)  			     (unsigned long)dev);  	} -	INIT_LIST_HEAD(&priv->alg_list); -  	priv->reg = of_iomap(np, 0);  	if (!priv->reg) {  		dev_err(dev, "failed to of_iomap\n");  | 
