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