diff options
-rw-r--r-- | drivers/crypto/picoxcell_crypto.c | 64 |
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 | ||
179 | static int spacc_ablk_submit(struct spacc_req *req); | ||
180 | |||
179 | static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) | 181 | static 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 | ||
671 | static int spacc_req_submit(struct spacc_req *req); | ||
672 | |||
673 | static 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 |