1024a8abbSNagadheeraj Rottela /* SPDX-License-Identifier: BSD-3-Clause 2024a8abbSNagadheeraj Rottela * Copyright(C) 2019 Marvell International Ltd. 3024a8abbSNagadheeraj Rottela */ 4024a8abbSNagadheeraj Rottela 5024a8abbSNagadheeraj Rottela #include <rte_memzone.h> 6024a8abbSNagadheeraj Rottela #include <rte_malloc.h> 7024a8abbSNagadheeraj Rottela 8024a8abbSNagadheeraj Rottela #include "nitrox_qp.h" 9024a8abbSNagadheeraj Rottela #include "nitrox_hal.h" 10024a8abbSNagadheeraj Rottela #include "nitrox_logs.h" 11024a8abbSNagadheeraj Rottela 12024a8abbSNagadheeraj Rottela #define MAX_CMD_QLEN 16384 13024a8abbSNagadheeraj Rottela #define CMDQ_PKT_IN_ALIGN 16 14024a8abbSNagadheeraj Rottela 15024a8abbSNagadheeraj Rottela static int 16024a8abbSNagadheeraj Rottela nitrox_setup_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr, 17024a8abbSNagadheeraj Rottela const char *dev_name, uint8_t instr_size, int socket_id) 18024a8abbSNagadheeraj Rottela { 19024a8abbSNagadheeraj Rottela char mz_name[RTE_MEMZONE_NAMESIZE]; 20024a8abbSNagadheeraj Rottela const struct rte_memzone *mz; 21024a8abbSNagadheeraj Rottela size_t cmdq_size = qp->count * instr_size; 22024a8abbSNagadheeraj Rottela uint64_t offset; 23751ea2c0SNagadheeraj Rottela int err = 0; 24024a8abbSNagadheeraj Rottela 25024a8abbSNagadheeraj Rottela snprintf(mz_name, sizeof(mz_name), "%s_cmdq_%d", dev_name, qp->qno); 26024a8abbSNagadheeraj Rottela mz = rte_memzone_reserve_aligned(mz_name, cmdq_size, socket_id, 27024a8abbSNagadheeraj Rottela RTE_MEMZONE_SIZE_HINT_ONLY | 28024a8abbSNagadheeraj Rottela RTE_MEMZONE_256MB, 29024a8abbSNagadheeraj Rottela CMDQ_PKT_IN_ALIGN); 30024a8abbSNagadheeraj Rottela if (!mz) { 31*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "cmdq memzone reserve failed for %s queue", 32024a8abbSNagadheeraj Rottela mz_name); 33024a8abbSNagadheeraj Rottela return -ENOMEM; 34024a8abbSNagadheeraj Rottela } 35024a8abbSNagadheeraj Rottela 36751ea2c0SNagadheeraj Rottela switch (qp->type) { 37751ea2c0SNagadheeraj Rottela case NITROX_QUEUE_SE: 38024a8abbSNagadheeraj Rottela offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(qp->qno); 39024a8abbSNagadheeraj Rottela qp->cmdq.dbell_csr_addr = NITROX_CSR_ADDR(bar_addr, offset); 40751ea2c0SNagadheeraj Rottela setup_nps_pkt_input_ring(bar_addr, qp->qno, qp->count, 41751ea2c0SNagadheeraj Rottela mz->iova); 42751ea2c0SNagadheeraj Rottela setup_nps_pkt_solicit_output_port(bar_addr, qp->qno); 43751ea2c0SNagadheeraj Rottela break; 44751ea2c0SNagadheeraj Rottela case NITROX_QUEUE_ZIP: 45751ea2c0SNagadheeraj Rottela offset = ZQMQ_DRBLX(qp->qno); 46751ea2c0SNagadheeraj Rottela qp->cmdq.dbell_csr_addr = NITROX_CSR_ADDR(bar_addr, offset); 47751ea2c0SNagadheeraj Rottela err = setup_zqmq_input_ring(bar_addr, qp->qno, qp->count, 48751ea2c0SNagadheeraj Rottela mz->iova); 49751ea2c0SNagadheeraj Rottela break; 50751ea2c0SNagadheeraj Rottela default: 51*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid queue type %d", qp->type); 52751ea2c0SNagadheeraj Rottela err = -EINVAL; 53751ea2c0SNagadheeraj Rottela break; 54751ea2c0SNagadheeraj Rottela } 55751ea2c0SNagadheeraj Rottela 56751ea2c0SNagadheeraj Rottela if (err) { 57751ea2c0SNagadheeraj Rottela rte_memzone_free(mz); 58751ea2c0SNagadheeraj Rottela return err; 59751ea2c0SNagadheeraj Rottela } 60751ea2c0SNagadheeraj Rottela 61751ea2c0SNagadheeraj Rottela qp->cmdq.mz = mz; 62024a8abbSNagadheeraj Rottela qp->cmdq.ring = mz->addr; 63024a8abbSNagadheeraj Rottela qp->cmdq.instr_size = instr_size; 64024a8abbSNagadheeraj Rottela return 0; 65024a8abbSNagadheeraj Rottela } 66024a8abbSNagadheeraj Rottela 67024a8abbSNagadheeraj Rottela static int 68024a8abbSNagadheeraj Rottela nitrox_setup_ridq(struct nitrox_qp *qp, int socket_id) 69024a8abbSNagadheeraj Rottela { 70024a8abbSNagadheeraj Rottela size_t ridq_size = qp->count * sizeof(*qp->ridq); 71024a8abbSNagadheeraj Rottela 72024a8abbSNagadheeraj Rottela qp->ridq = rte_zmalloc_socket("nitrox ridq", ridq_size, 73024a8abbSNagadheeraj Rottela RTE_CACHE_LINE_SIZE, 74024a8abbSNagadheeraj Rottela socket_id); 75024a8abbSNagadheeraj Rottela if (!qp->ridq) { 76*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Failed to create rid queue"); 77024a8abbSNagadheeraj Rottela return -ENOMEM; 78024a8abbSNagadheeraj Rottela } 79024a8abbSNagadheeraj Rottela 80024a8abbSNagadheeraj Rottela return 0; 81024a8abbSNagadheeraj Rottela } 82024a8abbSNagadheeraj Rottela 83024a8abbSNagadheeraj Rottela static int 84024a8abbSNagadheeraj Rottela nitrox_release_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr) 85024a8abbSNagadheeraj Rottela { 86751ea2c0SNagadheeraj Rottela int err = 0; 87751ea2c0SNagadheeraj Rottela 88751ea2c0SNagadheeraj Rottela switch (qp->type) { 89751ea2c0SNagadheeraj Rottela case NITROX_QUEUE_SE: 90024a8abbSNagadheeraj Rottela nps_pkt_solicited_port_disable(bar_addr, qp->qno); 91024a8abbSNagadheeraj Rottela nps_pkt_input_ring_disable(bar_addr, qp->qno); 92751ea2c0SNagadheeraj Rottela break; 93751ea2c0SNagadheeraj Rottela case NITROX_QUEUE_ZIP: 94751ea2c0SNagadheeraj Rottela err = zqmq_input_ring_disable(bar_addr, qp->qno); 95751ea2c0SNagadheeraj Rottela break; 96751ea2c0SNagadheeraj Rottela default: 97751ea2c0SNagadheeraj Rottela err = -EINVAL; 98751ea2c0SNagadheeraj Rottela } 99751ea2c0SNagadheeraj Rottela 100751ea2c0SNagadheeraj Rottela if (err) 101751ea2c0SNagadheeraj Rottela return err; 102751ea2c0SNagadheeraj Rottela 103024a8abbSNagadheeraj Rottela return rte_memzone_free(qp->cmdq.mz); 104024a8abbSNagadheeraj Rottela } 105024a8abbSNagadheeraj Rottela 106024a8abbSNagadheeraj Rottela int 107024a8abbSNagadheeraj Rottela nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name, 108024a8abbSNagadheeraj Rottela uint32_t nb_descriptors, uint8_t instr_size, int socket_id) 109024a8abbSNagadheeraj Rottela { 110024a8abbSNagadheeraj Rottela int err; 111024a8abbSNagadheeraj Rottela uint32_t count; 112024a8abbSNagadheeraj Rottela 113024a8abbSNagadheeraj Rottela count = rte_align32pow2(nb_descriptors); 114024a8abbSNagadheeraj Rottela if (count > MAX_CMD_QLEN) { 115*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "%s: Number of descriptors too big %d," 116*e99981afSDavid Marchand " greater than max queue length %d", 117024a8abbSNagadheeraj Rottela dev_name, count, 118024a8abbSNagadheeraj Rottela MAX_CMD_QLEN); 119024a8abbSNagadheeraj Rottela return -EINVAL; 120024a8abbSNagadheeraj Rottela } 121024a8abbSNagadheeraj Rottela 122751ea2c0SNagadheeraj Rottela qp->bar_addr = bar_addr; 123024a8abbSNagadheeraj Rottela qp->count = count; 124024a8abbSNagadheeraj Rottela qp->head = qp->tail = 0; 125751ea2c0SNagadheeraj Rottela rte_atomic_store_explicit(&qp->pending_count, 0, 126751ea2c0SNagadheeraj Rottela rte_memory_order_relaxed); 127024a8abbSNagadheeraj Rottela err = nitrox_setup_cmdq(qp, bar_addr, dev_name, instr_size, socket_id); 128024a8abbSNagadheeraj Rottela if (err) 129024a8abbSNagadheeraj Rottela return err; 130024a8abbSNagadheeraj Rottela 131024a8abbSNagadheeraj Rottela err = nitrox_setup_ridq(qp, socket_id); 132024a8abbSNagadheeraj Rottela if (err) 133024a8abbSNagadheeraj Rottela goto ridq_err; 134024a8abbSNagadheeraj Rottela 135024a8abbSNagadheeraj Rottela return 0; 136024a8abbSNagadheeraj Rottela 137024a8abbSNagadheeraj Rottela ridq_err: 138024a8abbSNagadheeraj Rottela nitrox_release_cmdq(qp, bar_addr); 139024a8abbSNagadheeraj Rottela return err; 140024a8abbSNagadheeraj Rottela } 141024a8abbSNagadheeraj Rottela 142024a8abbSNagadheeraj Rottela static void 143024a8abbSNagadheeraj Rottela nitrox_release_ridq(struct nitrox_qp *qp) 144024a8abbSNagadheeraj Rottela { 145024a8abbSNagadheeraj Rottela rte_free(qp->ridq); 146024a8abbSNagadheeraj Rottela } 147024a8abbSNagadheeraj Rottela 148024a8abbSNagadheeraj Rottela int 149024a8abbSNagadheeraj Rottela nitrox_qp_release(struct nitrox_qp *qp, uint8_t *bar_addr) 150024a8abbSNagadheeraj Rottela { 151024a8abbSNagadheeraj Rottela nitrox_release_ridq(qp); 152024a8abbSNagadheeraj Rottela return nitrox_release_cmdq(qp, bar_addr); 153024a8abbSNagadheeraj Rottela } 154