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