u8 salt[AES_BLOCK_SIZE];
};
+static int spacc_ablk_submit(struct spacc_req *req);
+
static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg)
{
return alg ? container_of(alg, struct spacc_alg, alg) : NULL;
return -EINPROGRESS;
}
+static int spacc_req_submit(struct spacc_req *req);
+
+static void spacc_push(struct spacc_engine *engine)
+{
+ struct spacc_req *req;
+
+ while (!list_empty(&engine->pending) &&
+ engine->in_flight + 1 <= engine->fifo_sz) {
+
+ ++engine->in_flight;
+ req = list_first_entry(&engine->pending, struct spacc_req,
+ list);
+ list_move_tail(&req->list, &engine->in_progress);
+
+ req->result = spacc_req_submit(req);
+ }
+}
+
/*
* Setup an AEAD request for processing. This will configure the engine, load
* the context and then start the packet processing.
err = -EINPROGRESS;
spin_lock_irqsave(&engine->hw_lock, flags);
- if (unlikely(spacc_fifo_cmd_full(engine))) {
+ if (unlikely(spacc_fifo_cmd_full(engine)) ||
+ engine->in_flight + 1 > engine->fifo_sz) {
if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
err = -EBUSY;
spin_unlock_irqrestore(&engine->hw_lock, flags);
}
list_add_tail(&dev_req->list, &engine->pending);
} else {
- ++engine->in_flight;
- list_add_tail(&dev_req->list, &engine->in_progress);
- spacc_aead_submit(dev_req);
+ list_add_tail(&dev_req->list, &engine->pending);
+ spacc_push(engine);
}
spin_unlock_irqrestore(&engine->hw_lock, flags);
* we either stick it on the end of a pending list if we can backlog,
* or bailout with an error if not.
*/
- if (unlikely(spacc_fifo_cmd_full(engine))) {
+ if (unlikely(spacc_fifo_cmd_full(engine)) ||
+ engine->in_flight + 1 > engine->fifo_sz) {
if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
err = -EBUSY;
spin_unlock_irqrestore(&engine->hw_lock, flags);
}
list_add_tail(&dev_req->list, &engine->pending);
} else {
- ++engine->in_flight;
- list_add_tail(&dev_req->list, &engine->in_progress);
- spacc_ablk_submit(dev_req);
+ list_add_tail(&dev_req->list, &engine->pending);
+ spacc_push(engine);
}
spin_unlock_irqrestore(&engine->hw_lock, flags);
req = list_first_entry(&engine->in_progress, struct spacc_req,
list);
list_move_tail(&req->list, &engine->completed);
+ --engine->in_flight;
/* POP the status register. */
writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET);
struct spacc_engine *engine = (struct spacc_engine *)data;
struct spacc_req *req, *tmp;
unsigned long flags;
- int num_removed = 0;
LIST_HEAD(completed);
spin_lock_irqsave(&engine->hw_lock, flags);
+
list_splice_init(&engine->completed, &completed);
+ spacc_push(engine);
+ if (engine->in_flight)
+ mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
+
spin_unlock_irqrestore(&engine->hw_lock, flags);
list_for_each_entry_safe(req, tmp, &completed, list) {
- ++num_removed;
req->complete(req);
+ list_del(&req->list);
}
-
- /* Try and fill the engine back up again. */
- spin_lock_irqsave(&engine->hw_lock, flags);
-
- engine->in_flight -= num_removed;
-
- list_for_each_entry_safe(req, tmp, &engine->pending, list) {
- if (spacc_fifo_cmd_full(engine))
- break;
-
- list_move_tail(&req->list, &engine->in_progress);
- ++engine->in_flight;
- req->result = spacc_req_submit(req);
- }
-
- if (engine->in_flight)
- mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
-
- spin_unlock_irqrestore(&engine->hw_lock, flags);
}
#ifdef CONFIG_PM