/* * We do indeed write all 6 command words to the same * register. The HW supports this.
*/
for (i = 0; i < seq_len; i++) { for (w = 0; w <= 5; w++)
writel_relaxed(seq[i].word[w], reg);
if (cc_dump_desc)
dev_dbg(dev, "desc[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
i, seq[i].word[0], seq[i].word[1],
seq[i].word[2], seq[i].word[3],
seq[i].word[4], seq[i].word[5]);
}
}
/** * request_mgr_complete() - Completion will take place if and only if user * requested completion by cc_send_sync_request(). * * @dev: Device pointer * @dx_compl_h: The completion event to signal * @dummy: unused error code
*/ staticvoid request_mgr_complete(struct device *dev, void *dx_compl_h, int dummy)
{ struct completion *this_compl = dx_compl_h;
/* SW queue is checked only once as it will not * be changed during the poll because the spinlock_bh * is held by the thread
*/ if (((req_mgr_h->req_queue_head + 1) & (MAX_REQUEST_QUEUE_SIZE - 1)) ==
req_mgr_h->req_queue_tail) {
dev_err(dev, "SW FIFO is full. req_queue_head=%d sw_fifo_len=%d\n",
req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE); return -ENOSPC;
}
if (req_mgr_h->q_free_slots >= total_seq_len) return 0;
/* Wait for space in HW queue. Poll constant num of iterations. */ for (poll_queue = 0; poll_queue < CC_MAX_POLL_ITER ; poll_queue++) {
req_mgr_h->q_free_slots =
cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); if (req_mgr_h->q_free_slots < req_mgr_h->min_free_hw_slots)
req_mgr_h->min_free_hw_slots = req_mgr_h->q_free_slots;
if (req_mgr_h->q_free_slots >= total_seq_len) { /* If there is enough place return */ return 0;
}
dev_dbg(dev, "HW FIFO is full. q_free_slots=%d total_seq_len=%d\n",
req_mgr_h->q_free_slots, total_seq_len);
} /* No room in the HW queue try again later */
dev_dbg(dev, "HW FIFO full, timeout. req_queue_head=%d sw_fifo_len=%d q_free_slots=%d total_seq_len=%d\n",
req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE,
req_mgr_h->q_free_slots, total_seq_len); return -ENOSPC;
}
/** * cc_do_send_request() - Enqueue caller request to crypto hardware. * Need to be called with HW lock held and PM running * * @drvdata: Associated device driver context * @cc_req: The request to enqueue * @desc: The crypto sequence * @len: The crypto sequence length * @add_comp: If "true": add an artificial dout DMA to mark completion *
*/ staticvoid cc_do_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req, struct cc_hw_desc *desc, unsignedint len, bool add_comp)
{ struct cc_req_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; unsignedint used_sw_slots; unsignedint total_seq_len = len; /*initial sequence length*/ struct device *dev = drvdata_to_dev(drvdata);
/* * We are about to push command to the HW via the command registers * that may reference host memory. We need to issue a memory barrier * to make sure there are no outstanding memory writes
*/
wmb();
/* STAT_PHASE_4: Push sequence */
enqueue_seq(drvdata, desc, len);
if (add_comp) {
enqueue_seq(drvdata, &req_mgr_h->compl_desc, 1);
total_seq_len++;
}
if (req_mgr_h->q_free_slots < total_seq_len) { /* This situation should never occur. Maybe indicating problem * with resuming power. Set the free slot count to 0 and hope * for the best.
*/
dev_err(dev, "HW free slot count mismatch.");
req_mgr_h->q_free_slots = 0;
} else { /* Update the free slots in HW queue */
req_mgr_h->q_free_slots -= total_seq_len;
}
}
while (mgr->bl_len) {
bli = list_first_entry(&mgr->backlog, struct cc_bl_item, list);
dev_dbg(dev, "---bl len: %d\n", mgr->bl_len);
spin_unlock(&mgr->bl_lock);
creq = &bli->creq;
req = creq->user_arg;
/* * Notify the request we're moving out of the backlog * but only if we haven't done so already.
*/ if (!bli->notif) {
creq->user_cb(dev, req, -EINPROGRESS);
bli->notif = true;
}
spin_lock(&mgr->hw_lock);
rc = cc_queues_status(drvdata, mgr, bli->len); if (rc) { /* * There is still no room in the FIFO for * this request. Bail out. We'll return here * on the next completion irq.
*/
spin_unlock(&mgr->hw_lock); return;
}
/** * send_request_init() - Enqueue caller request to crypto hardware during init * process. * Assume this function is not called in the middle of a flow, * since we set QUEUE_LAST_IND flag in the last descriptor. * * @drvdata: Associated device driver context * @desc: The crypto sequence * @len: The crypto sequence length * * Return: * Returns "0" upon success
*/ int send_request_init(struct cc_drvdata *drvdata, struct cc_hw_desc *desc, unsignedint len)
{ struct cc_req_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; unsignedint total_seq_len = len; /*initial sequence length*/ int rc = 0;
/* Wait for space in HW and SW FIFO. Poll for as much as FIFO_TIMEOUT.
*/
rc = cc_queues_status(drvdata, req_mgr_h, total_seq_len); if (rc) return rc;
set_queue_last_ind(drvdata, &desc[(len - 1)]);
/* * We are about to push command to the HW via the command registers * that may reference host memory. We need to issue a memory barrier * to make sure there are no outstanding memory writes
*/
wmb();
enqueue_seq(drvdata, desc, len);
/* Update the free slots in HW queue */
req_mgr_h->q_free_slots =
cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT));
while (request_mgr_handle->axi_completed) {
request_mgr_handle->axi_completed--;
/* Dequeue request */ if (*head == *tail) { /* We are supposed to handle a completion but our * queue is empty. This is not normal. Return and * hope for the best.
*/
dev_err(dev, "Request queue is empty head == tail %u\n",
*head); break;
}
dev_dbg(dev, "AXI completion after updated: %d\n",
request_mgr_handle->axi_completed);
while (request_mgr_handle->axi_completed) { do {
drvdata->irq |= cc_ioread(drvdata, CC_REG(HOST_IRR));
irq = (drvdata->irq & drvdata->comp_mask);
proc_completions(drvdata);
/* At this point (after proc_completions()), * request_mgr_handle->axi_completed is 0.
*/
request_mgr_handle->axi_completed +=
cc_axi_comp_count(drvdata);
} while (request_mgr_handle->axi_completed > 0);
/* after verifying that there is nothing to do, * unmask AXI completion interrupt
*/
cc_iowrite(drvdata, CC_REG(HOST_IMR),
cc_ioread(drvdata, CC_REG(HOST_IMR)) & ~drvdata->comp_mask);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.2Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.