^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Marvell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Antoine Tenart <antoine.tenart@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "safexcel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) int safexcel_init_ring_descriptors(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct safexcel_desc_ring *cdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct safexcel_desc_ring *rdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct safexcel_command_desc *cdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) dma_addr_t atok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* Actual command descriptor ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) cdr->offset = priv->config.cd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) cdr->base = dmam_alloc_coherent(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) cdr->offset * EIP197_DEFAULT_RING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) &cdr->base_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (!cdr->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) cdr->write = cdr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) cdr->base_end = cdr->base + cdr->offset * (EIP197_DEFAULT_RING_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) cdr->read = cdr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Command descriptor shadow ring for storing additional token data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) cdr->shoffset = priv->config.cdsh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) cdr->shbase = dmam_alloc_coherent(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) cdr->shoffset *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) EIP197_DEFAULT_RING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) &cdr->shbase_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (!cdr->shbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) cdr->shwrite = cdr->shbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) cdr->shbase_end = cdr->shbase + cdr->shoffset *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (EIP197_DEFAULT_RING_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Populate command descriptors with physical pointers to shadow descs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Note that we only need to do this once if we don't overwrite them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) cdesc = cdr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) atok = cdr->shbase_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) for (i = 0; i < EIP197_DEFAULT_RING_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) cdesc->atok_lo = lower_32_bits(atok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) cdesc->atok_hi = upper_32_bits(atok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) cdesc = (void *)cdesc + cdr->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) atok += cdr->shoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) rdr->offset = priv->config.rd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Use shoffset for result token offset here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) rdr->shoffset = priv->config.res_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) rdr->base = dmam_alloc_coherent(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) rdr->offset * EIP197_DEFAULT_RING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) &rdr->base_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!rdr->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rdr->write = rdr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) rdr->base_end = rdr->base + rdr->offset * (EIP197_DEFAULT_RING_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) rdr->read = rdr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) inline int safexcel_select_ring(struct safexcel_crypto_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return (atomic_inc_return(&priv->ring_used) % priv->config.rings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void *safexcel_ring_next_cwptr(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct safexcel_desc_ring *ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) bool first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct safexcel_token **atoken)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void *ptr = ring->write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *atoken = ring->shwrite;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if ((ring->write == ring->read - ring->offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) (ring->read == ring->base && ring->write == ring->base_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ring->write == ring->base_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ring->write = ring->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ring->shwrite = ring->shbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ring->write += ring->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ring->shwrite += ring->shoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void *safexcel_ring_next_rwptr(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct safexcel_desc_ring *ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct result_data_desc **rtoken)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void *ptr = ring->write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Result token at relative offset shoffset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *rtoken = ring->write + ring->shoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if ((ring->write == ring->read - ring->offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) (ring->read == ring->base && ring->write == ring->base_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ring->write == ring->base_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ring->write = ring->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ring->write += ring->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void *safexcel_ring_next_rptr(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct safexcel_desc_ring *ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) void *ptr = ring->read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ring->write == ring->read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ring->read == ring->base_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ring->read = ring->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ring->read += ring->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) inline void *safexcel_ring_curr_rptr(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct safexcel_desc_ring *rdr = &priv->ring[ring].rdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return rdr->read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) inline int safexcel_ring_first_rdr_index(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct safexcel_desc_ring *rdr = &priv->ring[ring].rdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return (rdr->read - rdr->base) / rdr->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) inline int safexcel_ring_rdr_rdesc_index(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct safexcel_result_desc *rdesc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct safexcel_desc_ring *rdr = &priv->ring[ring].rdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ((void *)rdesc - rdr->base) / rdr->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void safexcel_ring_rollback_wptr(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct safexcel_desc_ring *ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ring->write == ring->read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (ring->write == ring->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ring->write = ring->base_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ring->shwrite = ring->shbase_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ring->write -= ring->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ring->shwrite -= ring->shoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct safexcel_command_desc *safexcel_add_cdesc(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int ring_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) bool first, bool last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dma_addr_t data, u32 data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u32 full_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dma_addr_t context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct safexcel_token **atoken)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct safexcel_command_desc *cdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cdesc = safexcel_ring_next_cwptr(priv, &priv->ring[ring_id].cdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) first, atoken);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (IS_ERR(cdesc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return cdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) cdesc->particle_size = data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cdesc->rsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cdesc->last_seg = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) cdesc->first_seg = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cdesc->additional_cdata_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cdesc->rsvd1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) cdesc->data_lo = lower_32_bits(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cdesc->data_hi = upper_32_bits(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Note that the length here MUST be >0 or else the EIP(1)97
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * may hang. Newer EIP197 firmware actually incorporates this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * fix already, but that doesn't help the EIP97 and we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * also be running older firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) cdesc->control_data.packet_length = full_data_len ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cdesc->control_data.options = EIP197_OPTION_MAGIC_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) EIP197_OPTION_64BIT_CTX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EIP197_OPTION_CTX_CTRL_IN_CMD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) EIP197_OPTION_RC_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) cdesc->control_data.type = EIP197_TYPE_BCLA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cdesc->control_data.context_lo = lower_32_bits(context) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) EIP197_CONTEXT_SMALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) cdesc->control_data.context_hi = upper_32_bits(context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return cdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ring_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) bool first, bool last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dma_addr_t data, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct safexcel_result_desc *rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct result_data_desc *rtoken;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rdesc = safexcel_ring_next_rwptr(priv, &priv->ring[ring_id].rdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) &rtoken);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (IS_ERR(rdesc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rdesc->particle_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) rdesc->rsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rdesc->descriptor_overflow = 1; /* assume error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rdesc->buffer_overflow = 1; /* assume error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) rdesc->last_seg = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) rdesc->first_seg = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rdesc->result_size = EIP197_RD64_RESULT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) rdesc->rsvd1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) rdesc->data_lo = lower_32_bits(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rdesc->data_hi = upper_32_bits(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Clear length in result token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rtoken->packet_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Assume errors - HW will clear if not the case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rtoken->error_code = 0x7fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }