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