aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/picoxcell_crypto.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
index b092d0a6583..230b5b8cda1 100644
--- a/drivers/crypto/picoxcell_crypto.c
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -176,6 +176,8 @@ struct spacc_aead_ctx {
176 u8 salt[AES_BLOCK_SIZE]; 176 u8 salt[AES_BLOCK_SIZE];
177}; 177};
178 178
179static int spacc_ablk_submit(struct spacc_req *req);
180
179static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) 181static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg)
180{ 182{
181 return alg ? container_of(alg, struct spacc_alg, alg) : NULL; 183 return alg ? container_of(alg, struct spacc_alg, alg) : NULL;
@@ -666,6 +668,24 @@ static int spacc_aead_submit(struct spacc_req *req)
666 return -EINPROGRESS; 668 return -EINPROGRESS;
667} 669}
668 670
671static int spacc_req_submit(struct spacc_req *req);
672
673static void spacc_push(struct spacc_engine *engine)
674{
675 struct spacc_req *req;
676
677 while (!list_empty(&engine->pending) &&
678 engine->in_flight + 1 <= engine->fifo_sz) {
679
680 ++engine->in_flight;
681 req = list_first_entry(&engine->pending, struct spacc_req,
682 list);
683 list_move_tail(&req->list, &engine->in_progress);
684
685 req->result = spacc_req_submit(req);
686 }
687}
688
669/* 689/*
670 * Setup an AEAD request for processing. This will configure the engine, load 690 * Setup an AEAD request for processing. This will configure the engine, load
671 * the context and then start the packet processing. 691 * the context and then start the packet processing.
@@ -698,7 +718,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv,
698 718
699 err = -EINPROGRESS; 719 err = -EINPROGRESS;
700 spin_lock_irqsave(&engine->hw_lock, flags); 720 spin_lock_irqsave(&engine->hw_lock, flags);
701 if (unlikely(spacc_fifo_cmd_full(engine))) { 721 if (unlikely(spacc_fifo_cmd_full(engine)) ||
722 engine->in_flight + 1 > engine->fifo_sz) {
702 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 723 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
703 err = -EBUSY; 724 err = -EBUSY;
704 spin_unlock_irqrestore(&engine->hw_lock, flags); 725 spin_unlock_irqrestore(&engine->hw_lock, flags);
@@ -706,9 +727,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv,
706 } 727 }
707 list_add_tail(&dev_req->list, &engine->pending); 728 list_add_tail(&dev_req->list, &engine->pending);
708 } else { 729 } else {
709 ++engine->in_flight; 730 list_add_tail(&dev_req->list, &engine->pending);
710 list_add_tail(&dev_req->list, &engine->in_progress); 731 spacc_push(engine);
711 spacc_aead_submit(dev_req);
712 } 732 }
713 spin_unlock_irqrestore(&engine->hw_lock, flags); 733 spin_unlock_irqrestore(&engine->hw_lock, flags);
714 734
@@ -1041,7 +1061,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type,
1041 * we either stick it on the end of a pending list if we can backlog, 1061 * we either stick it on the end of a pending list if we can backlog,
1042 * or bailout with an error if not. 1062 * or bailout with an error if not.
1043 */ 1063 */
1044 if (unlikely(spacc_fifo_cmd_full(engine))) { 1064 if (unlikely(spacc_fifo_cmd_full(engine)) ||
1065 engine->in_flight + 1 > engine->fifo_sz) {
1045 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 1066 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
1046 err = -EBUSY; 1067 err = -EBUSY;
1047 spin_unlock_irqrestore(&engine->hw_lock, flags); 1068 spin_unlock_irqrestore(&engine->hw_lock, flags);
@@ -1049,9 +1070,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type,
1049 } 1070 }
1050 list_add_tail(&dev_req->list, &engine->pending); 1071 list_add_tail(&dev_req->list, &engine->pending);
1051 } else { 1072 } else {
1052 ++engine->in_flight; 1073 list_add_tail(&dev_req->list, &engine->pending);
1053 list_add_tail(&dev_req->list, &engine->in_progress); 1074 spacc_push(engine);
1054 spacc_ablk_submit(dev_req);
1055 } 1075 }
1056 spin_unlock_irqrestore(&engine->hw_lock, flags); 1076 spin_unlock_irqrestore(&engine->hw_lock, flags);
1057 1077
@@ -1139,6 +1159,7 @@ static void spacc_process_done(struct spacc_engine *engine)
1139 req = list_first_entry(&engine->in_progress, struct spacc_req, 1159 req = list_first_entry(&engine->in_progress, struct spacc_req,
1140 list); 1160 list);
1141 list_move_tail(&req->list, &engine->completed); 1161 list_move_tail(&req->list, &engine->completed);
1162 --engine->in_flight;
1142 1163
1143 /* POP the status register. */ 1164 /* POP the status register. */
1144 writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET); 1165 writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET);
@@ -1208,36 +1229,21 @@ static void spacc_spacc_complete(unsigned long data)
1208 struct spacc_engine *engine = (struct spacc_engine *)data; 1229 struct spacc_engine *engine = (struct spacc_engine *)data;
1209 struct spacc_req *req, *tmp; 1230 struct spacc_req *req, *tmp;
1210 unsigned long flags; 1231 unsigned long flags;
1211 int num_removed = 0;
1212 LIST_HEAD(completed); 1232 LIST_HEAD(completed);
1213 1233
1214 spin_lock_irqsave(&engine->hw_lock, flags); 1234 spin_lock_irqsave(&engine->hw_lock, flags);
1235
1215 list_splice_init(&engine->completed, &completed); 1236 list_splice_init(&engine->completed, &completed);
1237 spacc_push(engine);
1238 if (engine->in_flight)
1239 mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
1240
1216 spin_unlock_irqrestore(&engine->hw_lock, flags); 1241 spin_unlock_irqrestore(&engine->hw_lock, flags);
1217 1242
1218 list_for_each_entry_safe(req, tmp, &completed, list) { 1243 list_for_each_entry_safe(req, tmp, &completed, list) {
1219 ++num_removed;
1220 req->complete(req); 1244 req->complete(req);
1245 list_del(&req->list);
1221 } 1246 }
1222
1223 /* Try and fill the engine back up again. */
1224 spin_lock_irqsave(&engine->hw_lock, flags);
1225
1226 engine->in_flight -= num_removed;
1227
1228 list_for_each_entry_safe(req, tmp, &engine->pending, list) {
1229 if (spacc_fifo_cmd_full(engine))
1230 break;
1231
1232 list_move_tail(&req->list, &engine->in_progress);
1233 ++engine->in_flight;
1234 req->result = spacc_req_submit(req);
1235 }
1236
1237 if (engine->in_flight)
1238 mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
1239
1240 spin_unlock_irqrestore(&engine->hw_lock, flags);
1241} 1247}
1242 1248
1243#ifdef CONFIG_PM 1249#ifdef CONFIG_PM