xref: /dpdk/drivers/common/cnxk/roc_dpi.c (revision 29fd052d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #include <fcntl.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 
9 #include "roc_api.h"
10 #include "roc_priv.h"
11 
12 #define DPI_PF_MBOX_SYSFS_ENTRY "dpi_device_config"
13 
14 static inline int
15 send_msg_to_pf(struct plt_pci_addr *pci_addr, const char *value, int size)
16 {
17 	char buf[255] = {0};
18 	int res, fd;
19 
20 	res = snprintf(
21 		buf, sizeof(buf), "/sys/bus/pci/devices/" PCI_PRI_FMT "/%s",
22 		pci_addr->domain, pci_addr->bus, DPI_PF_DBDF_DEVICE & 0x7,
23 		DPI_PF_DBDF_FUNCTION & 0x7, DPI_PF_MBOX_SYSFS_ENTRY);
24 
25 	if ((res < 0) || ((size_t)res > sizeof(buf)))
26 		return -ERANGE;
27 
28 	fd = open(buf, O_WRONLY);
29 	if (fd < 0)
30 		return -EACCES;
31 
32 	res = write(fd, value, size);
33 	close(fd);
34 	if (res < 0)
35 		return -EACCES;
36 
37 	return 0;
38 }
39 
40 int
41 roc_dpi_enable(struct roc_dpi *dpi)
42 {
43 	plt_write64(0x1, dpi->rbase + DPI_VDMA_EN);
44 	return 0;
45 }
46 
47 int
48 roc_dpi_disable(struct roc_dpi *dpi)
49 {
50 	plt_write64(0x0, dpi->rbase + DPI_VDMA_EN);
51 	return 0;
52 }
53 
54 int
55 roc_dpi_configure(struct roc_dpi *roc_dpi)
56 {
57 	struct plt_pci_device *pci_dev;
58 	const struct plt_memzone *dpi_mz;
59 	dpi_mbox_msg_t mbox_msg;
60 	struct npa_pool_s pool;
61 	struct npa_aura_s aura;
62 	int rc, count, buflen;
63 	uint64_t aura_handle;
64 	plt_iova_t iova;
65 	char name[32];
66 
67 	if (!roc_dpi) {
68 		plt_err("roc_dpi is NULL");
69 		return -EINVAL;
70 	}
71 
72 	pci_dev = roc_dpi->pci_dev;
73 	memset(&pool, 0, sizeof(struct npa_pool_s));
74 	pool.nat_align = 1;
75 
76 	memset(&aura, 0, sizeof(aura));
77 	rc = roc_npa_pool_create(&aura_handle, DPI_CMD_QUEUE_SIZE,
78 				 DPI_CMD_QUEUE_BUFS, &aura, &pool);
79 	if (rc) {
80 		plt_err("Failed to create NPA pool, err %d\n", rc);
81 		return rc;
82 	}
83 
84 	snprintf(name, sizeof(name), "dpimem%d", roc_dpi->vfid);
85 	buflen = DPI_CMD_QUEUE_SIZE * DPI_CMD_QUEUE_BUFS;
86 	dpi_mz = plt_memzone_reserve_aligned(name, buflen, 0,
87 					     DPI_CMD_QUEUE_SIZE);
88 	if (dpi_mz == NULL) {
89 		plt_err("dpi memzone reserve failed");
90 		rc = -ENOMEM;
91 		goto err1;
92 	}
93 
94 	roc_dpi->mz = dpi_mz;
95 	iova = dpi_mz->iova;
96 	for (count = 0; count < DPI_CMD_QUEUE_BUFS; count++) {
97 		roc_npa_aura_op_free(aura_handle, 0, iova);
98 		iova += DPI_CMD_QUEUE_SIZE;
99 	}
100 
101 	roc_dpi->chunk_base = (void *)roc_npa_aura_op_alloc(aura_handle, 0);
102 	if (!roc_dpi->chunk_base) {
103 		plt_err("Failed to alloc buffer from NPA aura");
104 		rc = -ENOMEM;
105 		goto err2;
106 	}
107 
108 	roc_dpi->chunk_next = (void *)roc_npa_aura_op_alloc(aura_handle, 0);
109 	if (!roc_dpi->chunk_next) {
110 		plt_err("Failed to alloc buffer from NPA aura");
111 		rc = -ENOMEM;
112 		goto err2;
113 	}
114 
115 	roc_dpi->aura_handle = aura_handle;
116 	/* subtract 2 as they have already been alloc'ed above */
117 	roc_dpi->pool_size_m1 = (DPI_CMD_QUEUE_SIZE >> 3) - 2;
118 
119 	plt_write64(0x0, roc_dpi->rbase + DPI_VDMA_REQQ_CTL);
120 	plt_write64(((uint64_t)(roc_dpi->chunk_base) >> 7) << 7,
121 		    roc_dpi->rbase + DPI_VDMA_SADDR);
122 	mbox_msg.u[0] = 0;
123 	mbox_msg.u[1] = 0;
124 	/* DPI PF driver expects vfid starts from index 0 */
125 	mbox_msg.s.vfid = roc_dpi->vfid;
126 	mbox_msg.s.cmd = DPI_QUEUE_OPEN;
127 	mbox_msg.s.csize = DPI_CMD_QUEUE_SIZE;
128 	mbox_msg.s.aura = roc_npa_aura_handle_to_aura(aura_handle);
129 	mbox_msg.s.sso_pf_func = idev_sso_pffunc_get();
130 	mbox_msg.s.npa_pf_func = idev_npa_pffunc_get();
131 
132 	rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg,
133 			    sizeof(dpi_mbox_msg_t));
134 	if (rc < 0) {
135 		plt_err("Failed to send mbox message %d to DPI PF, err %d",
136 			mbox_msg.s.cmd, rc);
137 		goto err2;
138 	}
139 
140 	return rc;
141 
142 err2:
143 	plt_memzone_free(dpi_mz);
144 err1:
145 	roc_npa_pool_destroy(aura_handle);
146 	return rc;
147 }
148 
149 int
150 roc_dpi_dev_init(struct roc_dpi *roc_dpi)
151 {
152 	struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
153 	uint16_t vfid;
154 
155 	roc_dpi->rbase = pci_dev->mem_resource[0].addr;
156 	vfid = ((pci_dev->addr.devid & 0x1F) << 3) |
157 	       (pci_dev->addr.function & 0x7);
158 	vfid -= 1;
159 	roc_dpi->vfid = vfid;
160 	plt_spinlock_init(&roc_dpi->chunk_lock);
161 
162 	return 0;
163 }
164 
165 int
166 roc_dpi_dev_fini(struct roc_dpi *roc_dpi)
167 {
168 	struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
169 	dpi_mbox_msg_t mbox_msg;
170 	uint64_t reg;
171 	int rc;
172 
173 	/* Wait for SADDR to become idle */
174 	reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
175 	while (!(reg & BIT_ULL(63)))
176 		reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
177 
178 	mbox_msg.u[0] = 0;
179 	mbox_msg.u[1] = 0;
180 	mbox_msg.s.vfid = roc_dpi->vfid;
181 	mbox_msg.s.cmd = DPI_QUEUE_CLOSE;
182 
183 	rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg,
184 			    sizeof(dpi_mbox_msg_t));
185 	if (rc < 0)
186 		plt_err("Failed to send mbox message %d to DPI PF, err %d",
187 			mbox_msg.s.cmd, rc);
188 
189 	roc_npa_pool_destroy(roc_dpi->aura_handle);
190 	plt_memzone_free(roc_dpi->mz);
191 
192 	return rc;
193 }
194