1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2019 Marvell International Ltd. 3 */ 4 5 #include <rte_cryptodev.h> 6 #include <rte_malloc.h> 7 8 #include "nitrox_qp.h" 9 #include "nitrox_hal.h" 10 #include "nitrox_logs.h" 11 12 #define MAX_CMD_QLEN 16384 13 #define CMDQ_PKT_IN_ALIGN 16 14 15 static int 16 nitrox_setup_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr, 17 const char *dev_name, uint8_t instr_size, int socket_id) 18 { 19 char mz_name[RTE_MEMZONE_NAMESIZE]; 20 const struct rte_memzone *mz; 21 size_t cmdq_size = qp->count * instr_size; 22 uint64_t offset; 23 24 snprintf(mz_name, sizeof(mz_name), "%s_cmdq_%d", dev_name, qp->qno); 25 mz = rte_memzone_reserve_aligned(mz_name, cmdq_size, socket_id, 26 RTE_MEMZONE_SIZE_HINT_ONLY | 27 RTE_MEMZONE_256MB, 28 CMDQ_PKT_IN_ALIGN); 29 if (!mz) { 30 NITROX_LOG(ERR, "cmdq memzone reserve failed for %s queue\n", 31 mz_name); 32 return -ENOMEM; 33 } 34 35 qp->cmdq.mz = mz; 36 offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(qp->qno); 37 qp->cmdq.dbell_csr_addr = NITROX_CSR_ADDR(bar_addr, offset); 38 qp->cmdq.ring = mz->addr; 39 qp->cmdq.instr_size = instr_size; 40 setup_nps_pkt_input_ring(bar_addr, qp->qno, qp->count, mz->iova); 41 setup_nps_pkt_solicit_output_port(bar_addr, qp->qno); 42 43 return 0; 44 } 45 46 static int 47 nitrox_setup_ridq(struct nitrox_qp *qp, int socket_id) 48 { 49 size_t ridq_size = qp->count * sizeof(*qp->ridq); 50 51 qp->ridq = rte_zmalloc_socket("nitrox ridq", ridq_size, 52 RTE_CACHE_LINE_SIZE, 53 socket_id); 54 if (!qp->ridq) { 55 NITROX_LOG(ERR, "Failed to create rid queue\n"); 56 return -ENOMEM; 57 } 58 59 return 0; 60 } 61 62 static int 63 nitrox_release_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr) 64 { 65 nps_pkt_solicited_port_disable(bar_addr, qp->qno); 66 nps_pkt_input_ring_disable(bar_addr, qp->qno); 67 return rte_memzone_free(qp->cmdq.mz); 68 } 69 70 int 71 nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name, 72 uint32_t nb_descriptors, uint8_t instr_size, int socket_id) 73 { 74 int err; 75 uint32_t count; 76 77 count = rte_align32pow2(nb_descriptors); 78 if (count > MAX_CMD_QLEN) { 79 NITROX_LOG(ERR, "%s: Number of descriptors too big %d," 80 " greater than max queue length %d\n", 81 dev_name, count, 82 MAX_CMD_QLEN); 83 return -EINVAL; 84 } 85 86 qp->count = count; 87 qp->head = qp->tail = 0; 88 rte_atomic16_init(&qp->pending_count); 89 err = nitrox_setup_cmdq(qp, bar_addr, dev_name, instr_size, socket_id); 90 if (err) 91 return err; 92 93 err = nitrox_setup_ridq(qp, socket_id); 94 if (err) 95 goto ridq_err; 96 97 return 0; 98 99 ridq_err: 100 nitrox_release_cmdq(qp, bar_addr); 101 return err; 102 } 103 104 static void 105 nitrox_release_ridq(struct nitrox_qp *qp) 106 { 107 rte_free(qp->ridq); 108 } 109 110 int 111 nitrox_qp_release(struct nitrox_qp *qp, uint8_t *bar_addr) 112 { 113 nitrox_release_ridq(qp); 114 return nitrox_release_cmdq(qp, bar_addr); 115 } 116