xref: /dpdk/drivers/common/nitrox/nitrox_qp.c (revision e99981af34632ecce3bac82d05db97b08308f9b5)
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