LCOV - code coverage report
Current view: top level - drivers/crypto/ccp - ccp_dev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 211 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 120 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <dirent.h>
       6                 :            : #include <fcntl.h>
       7                 :            : #include <stdio.h>
       8                 :            : #include <string.h>
       9                 :            : #include <sys/mman.h>
      10                 :            : #include <sys/queue.h>
      11                 :            : #include <sys/types.h>
      12                 :            : #include <sys/file.h>
      13                 :            : #include <unistd.h>
      14                 :            : 
      15                 :            : #include <rte_hexdump.h>
      16                 :            : #include <rte_memzone.h>
      17                 :            : #include <rte_malloc.h>
      18                 :            : #include <rte_memory.h>
      19                 :            : #include <rte_spinlock.h>
      20                 :            : #include <rte_string_fns.h>
      21                 :            : 
      22                 :            : #include "ccp_dev.h"
      23                 :            : #include "ccp_pmd_private.h"
      24                 :            : 
      25                 :            : static TAILQ_HEAD(, ccp_device) ccp_list = TAILQ_HEAD_INITIALIZER(ccp_list);
      26                 :            : static int ccp_dev_id;
      27                 :            : 
      28                 :            : int
      29                 :          0 : ccp_dev_start(struct rte_cryptodev *dev)
      30                 :            : {
      31                 :          0 :         struct ccp_private *priv = dev->data->dev_private;
      32                 :            : 
      33                 :          0 :         priv->last_dev = TAILQ_FIRST(&ccp_list);
      34                 :          0 :         return 0;
      35                 :            : }
      36                 :            : 
      37                 :            : struct ccp_queue *
      38                 :          0 : ccp_allot_queue(struct rte_cryptodev *cdev, int slot_req)
      39                 :            : {
      40                 :            :         int i, ret = 0;
      41                 :            :         struct ccp_device *dev;
      42                 :          0 :         struct ccp_private *priv = cdev->data->dev_private;
      43                 :            : 
      44                 :          0 :         dev = TAILQ_NEXT(priv->last_dev, next);
      45         [ #  # ]:          0 :         if (unlikely(dev == NULL))
      46                 :          0 :                 dev = TAILQ_FIRST(&ccp_list);
      47                 :          0 :         priv->last_dev = dev;
      48         [ #  # ]:          0 :         if (dev->qidx >= dev->cmd_q_count)
      49                 :          0 :                 dev->qidx = 0;
      50         [ #  # ]:          0 :         ret = rte_atomic64_read(&dev->cmd_q[dev->qidx].free_slots);
      51         [ #  # ]:          0 :         if (ret >= slot_req)
      52                 :          0 :                 return &dev->cmd_q[dev->qidx];
      53         [ #  # ]:          0 :         for (i = 0; i < dev->cmd_q_count; i++) {
      54                 :          0 :                 dev->qidx++;
      55         [ #  # ]:          0 :                 if (dev->qidx >= dev->cmd_q_count)
      56                 :          0 :                         dev->qidx = 0;
      57         [ #  # ]:          0 :                 ret = rte_atomic64_read(&dev->cmd_q[dev->qidx].free_slots);
      58         [ #  # ]:          0 :                 if (ret >= slot_req)
      59                 :          0 :                         return &dev->cmd_q[dev->qidx];
      60                 :            :         }
      61                 :            :         return NULL;
      62                 :            : }
      63                 :            : 
      64                 :            : int
      65                 :          0 : ccp_read_hwrng(uint32_t *value)
      66                 :            : {
      67                 :            :         struct ccp_device *dev;
      68                 :            : 
      69         [ #  # ]:          0 :         TAILQ_FOREACH(dev, &ccp_list, next) {
      70                 :          0 :                 void *vaddr = (void *)(dev->pci->mem_resource[2].addr);
      71                 :            : 
      72         [ #  # ]:          0 :                 while (dev->hwrng_retries++ < CCP_MAX_TRNG_RETRIES) {
      73                 :          0 :                         *value = CCP_READ_REG(vaddr, TRNG_OUT_REG);
      74         [ #  # ]:          0 :                         if (*value) {
      75                 :          0 :                                 dev->hwrng_retries = 0;
      76                 :          0 :                                 return 0;
      77                 :            :                         }
      78                 :            :                 }
      79                 :          0 :                 dev->hwrng_retries = 0;
      80                 :            :         }
      81                 :            :         return -1;
      82                 :            : }
      83                 :            : 
      84                 :            : static const struct rte_memzone *
      85                 :          0 : ccp_queue_dma_zone_reserve(const char *queue_name,
      86                 :            :                            uint32_t queue_size,
      87                 :            :                            int socket_id)
      88                 :            : {
      89                 :            :         const struct rte_memzone *mz;
      90                 :            : 
      91                 :          0 :         mz = rte_memzone_lookup(queue_name);
      92         [ #  # ]:          0 :         if (mz != 0) {
      93   [ #  #  #  # ]:          0 :                 if (((size_t)queue_size <= mz->len) &&
      94                 :          0 :                     ((socket_id == SOCKET_ID_ANY) ||
      95         [ #  # ]:          0 :                      (socket_id == mz->socket_id))) {
      96                 :            :                         CCP_LOG_INFO("re-use memzone already "
      97                 :            :                                      "allocated for %s", queue_name);
      98                 :            :                         return mz;
      99                 :            :                 }
     100                 :          0 :                 CCP_LOG_ERR("Incompatible memzone already "
     101                 :            :                             "allocated %s, size %u, socket %d. "
     102                 :            :                             "Requested size %u, socket %u",
     103                 :            :                             queue_name, (uint32_t)mz->len,
     104                 :            :                             mz->socket_id, queue_size, socket_id);
     105                 :          0 :                 return NULL;
     106                 :            :         }
     107                 :            : 
     108                 :            :         CCP_LOG_INFO("Allocate memzone for %s, size %u on socket %u",
     109                 :            :                      queue_name, queue_size, socket_id);
     110                 :            : 
     111                 :          0 :         return rte_memzone_reserve_aligned(queue_name, queue_size,
     112                 :            :                         socket_id, RTE_MEMZONE_IOVA_CONTIG, queue_size);
     113                 :            : }
     114                 :            : 
     115                 :            : /* bitmap support apis */
     116                 :            : static inline void
     117                 :            : ccp_set_bit(unsigned long *bitmap, int n)
     118                 :            : {
     119                 :          0 :         rte_atomic_fetch_or_explicit((unsigned long __rte_atomic *)&bitmap[WORD_OFFSET(n)],
     120                 :            :                 (1UL << BIT_OFFSET(n)), rte_memory_order_seq_cst);
     121                 :          0 : }
     122                 :            : 
     123                 :            : static inline void
     124                 :            : ccp_clear_bit(unsigned long *bitmap, int n)
     125                 :            : {
     126                 :          0 :         rte_atomic_fetch_and_explicit((unsigned long __rte_atomic *)&bitmap[WORD_OFFSET(n)],
     127                 :            :                 ~(1UL << BIT_OFFSET(n)), rte_memory_order_seq_cst);
     128                 :          0 : }
     129                 :            : 
     130                 :            : static inline uint32_t
     131                 :            : ccp_get_bit(unsigned long *bitmap, int n)
     132                 :            : {
     133                 :          0 :         return ((bitmap[WORD_OFFSET(n)] & (1 << BIT_OFFSET(n))) != 0);
     134                 :            : }
     135                 :            : 
     136                 :            : 
     137                 :            : static inline uint32_t
     138                 :            : ccp_ffz(unsigned long word)
     139                 :            : {
     140                 :            :         unsigned long first_zero;
     141                 :            : 
     142                 :          0 :         first_zero = __builtin_ffsl(~word);
     143                 :          0 :         return first_zero ? (first_zero - 1) :
     144                 :            :                 BITS_PER_WORD;
     145                 :            : }
     146                 :            : 
     147                 :            : static inline uint32_t
     148                 :          0 : ccp_find_first_zero_bit(unsigned long *addr, uint32_t limit)
     149                 :            : {
     150                 :            :         uint32_t i;
     151                 :            :         uint32_t nwords = 0;
     152                 :            : 
     153                 :          0 :         nwords = (limit - 1) / BITS_PER_WORD + 1;
     154         [ #  # ]:          0 :         for (i = 0; i < nwords; i++) {
     155         [ #  # ]:          0 :                 if (addr[i] == 0UL)
     156                 :          0 :                         return i * BITS_PER_WORD;
     157         [ #  # ]:          0 :                 if (addr[i] < ~(0UL))
     158                 :            :                         break;
     159                 :            :         }
     160   [ #  #  #  # ]:          0 :         return (i == nwords) ? limit : i * BITS_PER_WORD + ccp_ffz(addr[i]);
     161                 :            : }
     162                 :            : 
     163                 :            : static void
     164                 :          0 : ccp_bitmap_set(unsigned long *map, unsigned int start, int len)
     165                 :            : {
     166                 :          0 :         unsigned long *p = map + WORD_OFFSET(start);
     167                 :          0 :         const unsigned int size = start + len;
     168                 :          0 :         int bits_to_set = BITS_PER_WORD - (start % BITS_PER_WORD);
     169                 :          0 :         unsigned long mask_to_set = CCP_BITMAP_FIRST_WORD_MASK(start);
     170                 :            : 
     171         [ #  # ]:          0 :         while (len - bits_to_set >= 0) {
     172                 :          0 :                 *p |= mask_to_set;
     173                 :            :                 len -= bits_to_set;
     174                 :            :                 bits_to_set = BITS_PER_WORD;
     175                 :            :                 mask_to_set = ~0UL;
     176                 :          0 :                 p++;
     177                 :            :         }
     178         [ #  # ]:          0 :         if (len) {
     179                 :          0 :                 mask_to_set &= CCP_BITMAP_LAST_WORD_MASK(size);
     180                 :          0 :                 *p |= mask_to_set;
     181                 :            :         }
     182                 :          0 : }
     183                 :            : 
     184                 :            : static void
     185                 :            : ccp_bitmap_clear(unsigned long *map, unsigned int start, int len)
     186                 :            : {
     187                 :            :         unsigned long *p = map + WORD_OFFSET(start);
     188                 :            :         const unsigned int size = start + len;
     189                 :            :         int bits_to_clear = BITS_PER_WORD - (start % BITS_PER_WORD);
     190                 :            :         unsigned long mask_to_clear = CCP_BITMAP_FIRST_WORD_MASK(start);
     191                 :            : 
     192                 :            :         while (len - bits_to_clear >= 0) {
     193                 :            :                 *p &= ~mask_to_clear;
     194                 :            :                 len -= bits_to_clear;
     195                 :            :                 bits_to_clear = BITS_PER_WORD;
     196                 :            :                 mask_to_clear = ~0UL;
     197                 :            :                 p++;
     198                 :            :         }
     199                 :            :         if (len) {
     200                 :            :                 mask_to_clear &= CCP_BITMAP_LAST_WORD_MASK(size);
     201                 :            :                 *p &= ~mask_to_clear;
     202                 :            :         }
     203                 :            : }
     204                 :            : 
     205                 :            : 
     206                 :            : static unsigned long
     207                 :          0 : _ccp_find_next_bit(const unsigned long *addr,
     208                 :            :                    unsigned long nbits,
     209                 :            :                    unsigned long start,
     210                 :            :                    unsigned long invert)
     211                 :            : {
     212                 :            :         unsigned long tmp;
     213                 :            : 
     214         [ #  # ]:          0 :         if (!nbits || start >= nbits)
     215                 :            :                 return nbits;
     216                 :            : 
     217                 :          0 :         tmp = addr[start / BITS_PER_WORD] ^ invert;
     218                 :            : 
     219                 :            :         /* Handle 1st word. */
     220                 :          0 :         tmp &= CCP_BITMAP_FIRST_WORD_MASK(start);
     221                 :          0 :         start = ccp_round_down(start, BITS_PER_WORD);
     222                 :            : 
     223         [ #  # ]:          0 :         while (!tmp) {
     224                 :          0 :                 start += BITS_PER_WORD;
     225         [ #  # ]:          0 :                 if (start >= nbits)
     226                 :            :                         return nbits;
     227                 :            : 
     228                 :          0 :                 tmp = addr[start / BITS_PER_WORD] ^ invert;
     229                 :            :         }
     230                 :            : 
     231                 :          0 :         return RTE_MIN(start + (ffs(tmp) - 1), nbits);
     232                 :            : }
     233                 :            : 
     234                 :            : static unsigned long
     235                 :            : ccp_find_next_bit(const unsigned long *addr,
     236                 :            :                   unsigned long size,
     237                 :            :                   unsigned long offset)
     238                 :            : {
     239                 :          0 :         return _ccp_find_next_bit(addr, size, offset, 0UL);
     240                 :            : }
     241                 :            : 
     242                 :            : static unsigned long
     243                 :            : ccp_find_next_zero_bit(const unsigned long *addr,
     244                 :            :                        unsigned long size,
     245                 :            :                        unsigned long offset)
     246                 :            : {
     247                 :          0 :         return _ccp_find_next_bit(addr, size, offset, ~0UL);
     248                 :            : }
     249                 :            : 
     250                 :            : /**
     251                 :            :  * bitmap_find_next_zero_area - find a contiguous aligned zero area
     252                 :            :  * @map: The address to base the search on
     253                 :            :  * @size: The bitmap size in bits
     254                 :            :  * @start: The bitnumber to start searching at
     255                 :            :  * @nr: The number of zeroed bits we're looking for
     256                 :            :  */
     257                 :            : static unsigned long
     258                 :          0 : ccp_bitmap_find_next_zero_area(unsigned long *map,
     259                 :            :                                unsigned long size,
     260                 :            :                                unsigned long start,
     261                 :            :                                unsigned int nr)
     262                 :            : {
     263                 :            :         unsigned long index, end, i;
     264                 :            : 
     265                 :          0 : again:
     266                 :            :         index = ccp_find_next_zero_bit(map, size, start);
     267                 :            : 
     268                 :          0 :         end = index + nr;
     269         [ #  # ]:          0 :         if (end > size)
     270                 :          0 :                 return end;
     271                 :            :         i = ccp_find_next_bit(map, end, index);
     272         [ #  # ]:          0 :         if (i < end) {
     273                 :          0 :                 start = i + 1;
     274                 :          0 :                 goto again;
     275                 :            :         }
     276                 :            :         return index;
     277                 :            : }
     278                 :            : 
     279                 :            : static uint32_t
     280                 :          0 : ccp_lsb_alloc(struct ccp_queue *cmd_q, unsigned int count)
     281                 :            : {
     282                 :            :         struct ccp_device *ccp;
     283                 :            :         int start;
     284                 :            : 
     285                 :            :         /* First look at the map for the queue */
     286         [ #  # ]:          0 :         if (cmd_q->lsb >= 0) {
     287                 :          0 :                 start = (uint32_t)ccp_bitmap_find_next_zero_area(cmd_q->lsbmap,
     288                 :            :                                                                  LSB_SIZE, 0,
     289                 :            :                                                                  count);
     290         [ #  # ]:          0 :                 if (start < LSB_SIZE) {
     291                 :          0 :                         ccp_bitmap_set(cmd_q->lsbmap, start, count);
     292                 :          0 :                         return start + cmd_q->lsb * LSB_SIZE;
     293                 :            :                 }
     294                 :            :         }
     295                 :            : 
     296                 :            :         /* try to get an entry from the shared blocks */
     297                 :          0 :         ccp = cmd_q->dev;
     298                 :            : 
     299                 :          0 :         rte_spinlock_lock(&ccp->lsb_lock);
     300                 :            : 
     301                 :          0 :         start = (uint32_t)ccp_bitmap_find_next_zero_area(ccp->lsbmap,
     302                 :            :                                                     MAX_LSB_CNT * LSB_SIZE,
     303                 :            :                                                     0, count);
     304         [ #  # ]:          0 :         if (start <= MAX_LSB_CNT * LSB_SIZE) {
     305                 :          0 :                 ccp_bitmap_set(ccp->lsbmap, start, count);
     306                 :            :                 rte_spinlock_unlock(&ccp->lsb_lock);
     307                 :          0 :                 return start * LSB_ITEM_SIZE;
     308                 :            :         }
     309                 :          0 :         CCP_LOG_ERR("NO LSBs available");
     310                 :            : 
     311                 :            :         rte_spinlock_unlock(&ccp->lsb_lock);
     312                 :            : 
     313                 :          0 :         return 0;
     314                 :            : }
     315                 :            : 
     316                 :            : static void __rte_unused
     317                 :            : ccp_lsb_free(struct ccp_queue *cmd_q,
     318                 :            :              unsigned int start,
     319                 :            :              unsigned int count)
     320                 :            : {
     321                 :            :         int lsbno = start / LSB_SIZE;
     322                 :            : 
     323                 :            :         if (!start)
     324                 :            :                 return;
     325                 :            : 
     326                 :            :         if (cmd_q->lsb == lsbno) {
     327                 :            :                 /* An entry from the private LSB */
     328                 :            :                 ccp_bitmap_clear(cmd_q->lsbmap, start % LSB_SIZE, count);
     329                 :            :         } else {
     330                 :            :                 /* From the shared LSBs */
     331                 :            :                 struct ccp_device *ccp = cmd_q->dev;
     332                 :            : 
     333                 :            :                 rte_spinlock_lock(&ccp->lsb_lock);
     334                 :            :                 ccp_bitmap_clear(ccp->lsbmap, start, count);
     335                 :            :                 rte_spinlock_unlock(&ccp->lsb_lock);
     336                 :            :         }
     337                 :            : }
     338                 :            : 
     339                 :            : static int
     340                 :          0 : ccp_find_lsb_regions(struct ccp_queue *cmd_q, uint64_t status)
     341                 :            : {
     342                 :          0 :         int q_mask = 1 << cmd_q->id;
     343                 :            :         int weight = 0;
     344                 :            :         int j;
     345                 :            : 
     346                 :            :         /* Build a bit mask to know which LSBs
     347                 :            :          * this queue has access to.
     348                 :            :          * Don't bother with segment 0
     349                 :            :          * as it has special
     350                 :            :          * privileges.
     351                 :            :          */
     352                 :          0 :         cmd_q->lsbmask = 0;
     353                 :          0 :         status >>= LSB_REGION_WIDTH;
     354         [ #  # ]:          0 :         for (j = 1; j < MAX_LSB_CNT; j++) {
     355         [ #  # ]:          0 :                 if (status & q_mask)
     356                 :          0 :                         ccp_set_bit(&cmd_q->lsbmask, j);
     357                 :            : 
     358                 :          0 :                 status >>= LSB_REGION_WIDTH;
     359                 :            :         }
     360                 :            : 
     361         [ #  # ]:          0 :         for (j = 0; j < MAX_LSB_CNT; j++)
     362         [ #  # ]:          0 :                 if (ccp_get_bit(&cmd_q->lsbmask, j))
     363                 :          0 :                         weight++;
     364                 :            : 
     365                 :            :         CCP_LOG_DBG("Queue %d can access %d LSB regions  of mask  %lu",
     366                 :            :                (int)cmd_q->id, weight, cmd_q->lsbmask);
     367                 :            : 
     368         [ #  # ]:          0 :         return weight ? 0 : -EINVAL;
     369                 :            : }
     370                 :            : 
     371                 :            : static int
     372                 :          0 : ccp_find_and_assign_lsb_to_q(struct ccp_device *ccp,
     373                 :            :                              int lsb_cnt, int n_lsbs,
     374                 :            :                              unsigned long *lsb_pub)
     375                 :            : {
     376                 :          0 :         unsigned long qlsb = 0;
     377                 :            :         int bitno = 0;
     378                 :            :         int qlsb_wgt = 0;
     379                 :            :         int i, j;
     380                 :            : 
     381                 :            :         /* For each queue:
     382                 :            :          * If the count of potential LSBs available to a queue matches the
     383                 :            :          * ordinal given to us in lsb_cnt:
     384                 :            :          * Copy the mask of possible LSBs for this queue into "qlsb";
     385                 :            :          * For each bit in qlsb, see if the corresponding bit in the
     386                 :            :          * aggregation mask is set; if so, we have a match.
     387                 :            :          *     If we have a match, clear the bit in the aggregation to
     388                 :            :          *     mark it as no longer available.
     389                 :            :          *     If there is no match, clear the bit in qlsb and keep looking.
     390                 :            :          */
     391         [ #  # ]:          0 :         for (i = 0; i < ccp->cmd_q_count; i++) {
     392                 :            :                 struct ccp_queue *cmd_q = &ccp->cmd_q[i];
     393                 :            : 
     394                 :            :                 qlsb_wgt = 0;
     395         [ #  # ]:          0 :                 for (j = 0; j < MAX_LSB_CNT; j++)
     396         [ #  # ]:          0 :                         if (ccp_get_bit(&cmd_q->lsbmask, j))
     397                 :          0 :                                 qlsb_wgt++;
     398                 :            : 
     399         [ #  # ]:          0 :                 if (qlsb_wgt == lsb_cnt) {
     400                 :          0 :                         qlsb = cmd_q->lsbmask;
     401                 :            : 
     402                 :          0 :                         bitno = ffs(qlsb) - 1;
     403         [ #  # ]:          0 :                         while (bitno < MAX_LSB_CNT) {
     404         [ #  # ]:          0 :                                 if (ccp_get_bit(lsb_pub, bitno)) {
     405                 :            :                                         /* We found an available LSB
     406                 :            :                                          * that this queue can access
     407                 :            :                                          */
     408                 :          0 :                                         cmd_q->lsb = bitno;
     409                 :            :                                         ccp_clear_bit(lsb_pub, bitno);
     410                 :            :                                         break;
     411                 :            :                                 }
     412                 :            :                                 ccp_clear_bit(&qlsb, bitno);
     413                 :          0 :                                 bitno = ffs(qlsb) - 1;
     414                 :            :                         }
     415         [ #  # ]:          0 :                         if (bitno >= MAX_LSB_CNT)
     416                 :            :                                 return -EINVAL;
     417                 :          0 :                         n_lsbs--;
     418                 :            :                 }
     419                 :            :         }
     420                 :            :         return n_lsbs;
     421                 :            : }
     422                 :            : 
     423                 :            : /* For each queue, from the most- to least-constrained:
     424                 :            :  * find an LSB that can be assigned to the queue. If there are N queues that
     425                 :            :  * can only use M LSBs, where N > M, fail; otherwise, every queue will get a
     426                 :            :  * dedicated LSB. Remaining LSB regions become a shared resource.
     427                 :            :  * If we have fewer LSBs than queues, all LSB regions become shared
     428                 :            :  * resources.
     429                 :            :  */
     430                 :            : static int
     431                 :          0 : ccp_assign_lsbs(struct ccp_device *ccp)
     432                 :            : {
     433                 :          0 :         unsigned long lsb_pub = 0, qlsb = 0;
     434                 :            :         int n_lsbs = 0;
     435                 :            :         int bitno;
     436                 :            :         int i, lsb_cnt;
     437                 :            :         int rc = 0;
     438                 :            : 
     439                 :            :         rte_spinlock_init(&ccp->lsb_lock);
     440                 :            : 
     441                 :            :         /* Create an aggregate bitmap to get a total count of available LSBs */
     442         [ #  # ]:          0 :         for (i = 0; i < ccp->cmd_q_count; i++)
     443                 :          0 :                 lsb_pub |= ccp->cmd_q[i].lsbmask;
     444                 :            : 
     445         [ #  # ]:          0 :         for (i = 0; i < MAX_LSB_CNT; i++)
     446         [ #  # ]:          0 :                 if (ccp_get_bit(&lsb_pub, i))
     447                 :          0 :                         n_lsbs++;
     448                 :            : 
     449         [ #  # ]:          0 :         if (n_lsbs >= ccp->cmd_q_count) {
     450                 :            :                 /* We have enough LSBS to give every queue a private LSB.
     451                 :            :                  * Brute force search to start with the queues that are more
     452                 :            :                  * constrained in LSB choice. When an LSB is privately
     453                 :            :                  * assigned, it is removed from the public mask.
     454                 :            :                  * This is an ugly N squared algorithm with some optimization.
     455                 :            :                  */
     456         [ #  # ]:          0 :                 for (lsb_cnt = 1; n_lsbs && (lsb_cnt <= MAX_LSB_CNT);
     457                 :          0 :                      lsb_cnt++) {
     458                 :          0 :                         rc = ccp_find_and_assign_lsb_to_q(ccp, lsb_cnt, n_lsbs,
     459                 :            :                                                           &lsb_pub);
     460         [ #  # ]:          0 :                         if (rc < 0)
     461                 :            :                                 return -EINVAL;
     462                 :            :                         n_lsbs = rc;
     463                 :            :                 }
     464                 :            :         }
     465                 :            : 
     466                 :            :         rc = 0;
     467                 :            :         /* What's left of the LSBs, according to the public mask, now become
     468                 :            :          * shared. Any zero bits in the lsb_pub mask represent an LSB region
     469                 :            :          * that can't be used as a shared resource, so mark the LSB slots for
     470                 :            :          * them as "in use".
     471                 :            :          */
     472                 :          0 :         qlsb = lsb_pub;
     473                 :          0 :         bitno = ccp_find_first_zero_bit(&qlsb, MAX_LSB_CNT);
     474         [ #  # ]:          0 :         while (bitno < MAX_LSB_CNT) {
     475                 :          0 :                 ccp_bitmap_set(ccp->lsbmap, bitno * LSB_SIZE, LSB_SIZE);
     476                 :            :                 ccp_set_bit(&qlsb, bitno);
     477                 :          0 :                 bitno = ccp_find_first_zero_bit(&qlsb, MAX_LSB_CNT);
     478                 :            :         }
     479                 :            : 
     480                 :            :         return rc;
     481                 :            : }
     482                 :            : 
     483                 :            : static int
     484                 :          0 : ccp_add_device(struct ccp_device *dev)
     485                 :            : {
     486                 :            :         int i;
     487                 :            :         uint32_t qmr, status_lo, status_hi, dma_addr_lo, dma_addr_hi;
     488                 :            :         uint64_t status;
     489                 :            :         struct ccp_queue *cmd_q;
     490                 :            :         const struct rte_memzone *q_mz;
     491                 :            :         void *vaddr;
     492                 :            : 
     493         [ #  # ]:          0 :         if (dev == NULL)
     494                 :            :                 return -1;
     495                 :            : 
     496                 :          0 :         dev->id = ccp_dev_id++;
     497                 :          0 :         dev->qidx = 0;
     498                 :          0 :         vaddr = (void *)(dev->pci->mem_resource[2].addr);
     499                 :            : 
     500         [ #  # ]:          0 :         if (dev->pci->id.device_id == AMD_PCI_CCP_5B) {
     501                 :            :                 CCP_WRITE_REG(vaddr, CMD_TRNG_CTL_OFFSET, 0x00012D57);
     502                 :            :                 CCP_WRITE_REG(vaddr, CMD_CONFIG_0_OFFSET, 0x00000003);
     503         [ #  # ]:          0 :                 for (i = 0; i < 12; i++) {
     504                 :            :                         CCP_WRITE_REG(vaddr, CMD_AES_MASK_OFFSET,
     505                 :            :                                       CCP_READ_REG(vaddr, TRNG_OUT_REG));
     506                 :            :                 }
     507                 :            :                 CCP_WRITE_REG(vaddr, CMD_QUEUE_MASK_OFFSET, 0x0000001F);
     508                 :            :                 CCP_WRITE_REG(vaddr, CMD_QUEUE_PRIO_OFFSET, 0x00005B6D);
     509                 :            :                 CCP_WRITE_REG(vaddr, CMD_CMD_TIMEOUT_OFFSET, 0x00000000);
     510                 :            : 
     511                 :            :                 CCP_WRITE_REG(vaddr, LSB_PRIVATE_MASK_LO_OFFSET, 0x3FFFFFFF);
     512                 :            :                 CCP_WRITE_REG(vaddr, LSB_PRIVATE_MASK_HI_OFFSET, 0x000003FF);
     513                 :            : 
     514                 :            :                 CCP_WRITE_REG(vaddr, CMD_CLK_GATE_CTL_OFFSET, 0x00108823);
     515                 :            :         }
     516                 :            :         CCP_WRITE_REG(vaddr, CMD_REQID_CONFIG_OFFSET, 0x0);
     517                 :            : 
     518                 :            :         /* Copy the private LSB mask to the public registers */
     519                 :            :         status_lo = CCP_READ_REG(vaddr, LSB_PRIVATE_MASK_LO_OFFSET);
     520                 :            :         status_hi = CCP_READ_REG(vaddr, LSB_PRIVATE_MASK_HI_OFFSET);
     521                 :            :         CCP_WRITE_REG(vaddr, LSB_PUBLIC_MASK_LO_OFFSET, status_lo);
     522                 :            :         CCP_WRITE_REG(vaddr, LSB_PUBLIC_MASK_HI_OFFSET, status_hi);
     523                 :          0 :         status = ((uint64_t)status_hi<<30) | ((uint64_t)status_lo);
     524                 :            : 
     525                 :          0 :         dev->cmd_q_count = 0;
     526                 :            :         /* Find available queues */
     527                 :            :         qmr = CCP_READ_REG(vaddr, Q_MASK_REG);
     528         [ #  # ]:          0 :         for (i = 0; i < MAX_HW_QUEUES; i++) {
     529         [ #  # ]:          0 :                 if (!(qmr & (1 << i)))
     530                 :          0 :                         continue;
     531                 :          0 :                 cmd_q = &dev->cmd_q[dev->cmd_q_count++];
     532                 :          0 :                 cmd_q->dev = dev;
     533                 :          0 :                 cmd_q->id = i;
     534                 :          0 :                 cmd_q->qidx = 0;
     535                 :          0 :                 cmd_q->qsize = Q_SIZE(Q_DESC_SIZE);
     536                 :            : 
     537                 :          0 :                 cmd_q->reg_base = (uint8_t *)vaddr +
     538                 :          0 :                         CMD_Q_STATUS_INCR * (i + 1);
     539                 :            : 
     540                 :            :                 /* CCP queue memory */
     541                 :          0 :                 snprintf(cmd_q->memz_name, sizeof(cmd_q->memz_name),
     542                 :            :                          "%s_%d_%s_%d_%s",
     543                 :            :                          "ccp_dev",
     544                 :            :                          (int)dev->id, "queue",
     545                 :            :                          (int)cmd_q->id, "mem");
     546                 :          0 :                 q_mz = ccp_queue_dma_zone_reserve(cmd_q->memz_name,
     547                 :          0 :                                                   cmd_q->qsize, SOCKET_ID_ANY);
     548                 :          0 :                 cmd_q->qbase_addr = (void *)q_mz->addr;
     549                 :          0 :                 cmd_q->qbase_desc = (void *)q_mz->addr;
     550                 :          0 :                 cmd_q->qbase_phys_addr =  q_mz->iova;
     551                 :            : 
     552                 :          0 :                 cmd_q->qcontrol = 0;
     553                 :            :                 /* init control reg to zero */
     554                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_CONTROL_BASE,
     555                 :            :                               cmd_q->qcontrol);
     556                 :            : 
     557                 :            :                 /* Disable the interrupts */
     558                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_INT_ENABLE_BASE, 0x00);
     559                 :          0 :                 CCP_READ_REG(cmd_q->reg_base, CMD_Q_INT_STATUS_BASE);
     560                 :          0 :                 CCP_READ_REG(cmd_q->reg_base, CMD_Q_STATUS_BASE);
     561                 :            : 
     562                 :            :                 /* Clear the interrupts */
     563                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_INTERRUPT_STATUS_BASE,
     564                 :            :                               ALL_INTERRUPTS);
     565                 :            : 
     566                 :            :                 /* Configure size of each virtual queue accessible to host */
     567                 :          0 :                 cmd_q->qcontrol &= ~(CMD_Q_SIZE << CMD_Q_SHIFT);
     568                 :          0 :                 cmd_q->qcontrol |= QUEUE_SIZE_VAL << CMD_Q_SHIFT;
     569                 :            : 
     570                 :          0 :                 dma_addr_lo = low32_value(cmd_q->qbase_phys_addr);
     571                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_TAIL_LO_BASE,
     572                 :            :                               (uint32_t)dma_addr_lo);
     573                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_HEAD_LO_BASE,
     574                 :            :                               (uint32_t)dma_addr_lo);
     575                 :            : 
     576                 :          0 :                 dma_addr_hi = high32_value(cmd_q->qbase_phys_addr);
     577                 :          0 :                 cmd_q->qcontrol |= (dma_addr_hi << 16);
     578                 :          0 :                 CCP_WRITE_REG(cmd_q->reg_base, CMD_Q_CONTROL_BASE,
     579                 :            :                               cmd_q->qcontrol);
     580                 :            : 
     581                 :            :                 /* create LSB Mask map */
     582         [ #  # ]:          0 :                 if (ccp_find_lsb_regions(cmd_q, status))
     583                 :          0 :                         CCP_LOG_ERR("queue doesn't have lsb regions");
     584                 :          0 :                 cmd_q->lsb = -1;
     585                 :            : 
     586                 :            :                 rte_atomic64_init(&cmd_q->free_slots);
     587                 :            :                 rte_atomic64_set(&cmd_q->free_slots, (COMMANDS_PER_QUEUE - 1));
     588                 :            :                 /* unused slot barrier b/w H&T */
     589                 :            :         }
     590                 :            : 
     591         [ #  # ]:          0 :         if (ccp_assign_lsbs(dev))
     592                 :          0 :                 CCP_LOG_ERR("Unable to assign lsb region");
     593                 :            : 
     594                 :            :         /* pre-allocate LSB slots */
     595         [ #  # ]:          0 :         for (i = 0; i < dev->cmd_q_count; i++) {
     596                 :          0 :                 dev->cmd_q[i].sb_key =
     597                 :          0 :                         ccp_lsb_alloc(&dev->cmd_q[i], 1);
     598                 :          0 :                 dev->cmd_q[i].sb_iv =
     599                 :          0 :                         ccp_lsb_alloc(&dev->cmd_q[i], 1);
     600                 :          0 :                 dev->cmd_q[i].sb_sha =
     601                 :          0 :                         ccp_lsb_alloc(&dev->cmd_q[i], 2);
     602                 :          0 :                 dev->cmd_q[i].sb_hmac =
     603                 :          0 :                         ccp_lsb_alloc(&dev->cmd_q[i], 2);
     604                 :            :         }
     605                 :            : 
     606                 :          0 :         TAILQ_INSERT_TAIL(&ccp_list, dev, next);
     607                 :          0 :         return 0;
     608                 :            : }
     609                 :            : 
     610                 :            : static void
     611                 :            : ccp_remove_device(struct ccp_device *dev)
     612                 :            : {
     613                 :            :         if (dev == NULL)
     614                 :            :                 return;
     615                 :            : 
     616         [ #  # ]:          0 :         TAILQ_REMOVE(&ccp_list, dev, next);
     617                 :            : }
     618                 :            : 
     619                 :            : int
     620                 :          0 : ccp_probe_device(struct rte_pci_device *pci_dev)
     621                 :            : {
     622                 :            :         struct ccp_device *ccp_dev;
     623                 :            : 
     624                 :          0 :         ccp_dev = rte_zmalloc("ccp_device", sizeof(*ccp_dev),
     625                 :            :                               RTE_CACHE_LINE_SIZE);
     626         [ #  # ]:          0 :         if (ccp_dev == NULL)
     627                 :          0 :                 goto fail;
     628                 :            : 
     629                 :          0 :         ccp_dev->pci = pci_dev;
     630                 :            : 
     631                 :            :         /* device is valid, add in list */
     632         [ #  # ]:          0 :         if (ccp_add_device(ccp_dev)) {
     633                 :            :                 ccp_remove_device(ccp_dev);
     634                 :          0 :                 goto fail;
     635                 :            :         }
     636                 :            : 
     637                 :            :         return 0;
     638                 :          0 : fail:
     639                 :          0 :         CCP_LOG_ERR("CCP Device probe failed");
     640                 :          0 :         rte_free(ccp_dev);
     641                 :          0 :         return -1;
     642                 :            : }

Generated by: LCOV version 1.14