Branch data Line data Source code
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 : 0 : send_msg_to_pf(struct plt_pci_addr *pci_addr, const char *value, int size)
17 : : {
18 : 0 : char buf[255] = {0};
19 : : int res, fd;
20 : :
21 : 0 : res = snprintf(
22 : : buf, sizeof(buf), "/sys/bus/pci/devices/" PCI_PRI_FMT "/%s",
23 [ # # ]: 0 : pci_addr->domain, pci_addr->bus, DPI_PF_DBDF_DEVICE & 0x7,
24 : : DPI_PF_DBDF_FUNCTION & 0x7, DPI_PF_MBOX_SYSFS_ENTRY);
25 : :
26 [ # # ]: 0 : if ((res < 0) || ((size_t)res > sizeof(buf)))
27 : : return -ERANGE;
28 : :
29 : : fd = open(buf, O_WRONLY);
30 [ # # ]: 0 : if (fd < 0)
31 : : return -EACCES;
32 : :
33 : 0 : res = write(fd, value, size);
34 : 0 : close(fd);
35 [ # # ]: 0 : if (res < 0)
36 : 0 : return -EACCES;
37 : :
38 : : return 0;
39 : : }
40 : :
41 : : int
42 : 0 : roc_dpi_wait_queue_idle(struct roc_dpi *roc_dpi)
43 : : {
44 : 0 : 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 : 0 : reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
50 [ # # ]: 0 : while (!(reg & BIT_ULL(63))) {
51 : 0 : reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
52 [ # # ]: 0 : if (plt_tsc_cycles() - start == cyc)
53 : : return -ETIMEDOUT;
54 : : }
55 : :
56 : : return 0;
57 : : }
58 : :
59 : : int
60 : 0 : roc_dpi_enable(struct roc_dpi *dpi)
61 : : {
62 : 0 : plt_write64(0x1, dpi->rbase + DPI_VDMA_EN);
63 : 0 : return 0;
64 : : }
65 : :
66 : : int
67 : 0 : roc_dpi_disable(struct roc_dpi *dpi)
68 : : {
69 : 0 : plt_write64(0x0, dpi->rbase + DPI_VDMA_EN);
70 : 0 : return 0;
71 : : }
72 : :
73 : : int
74 : 0 : 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 [ # # ]: 0 : if (!roc_dpi) {
81 : 0 : plt_err("roc_dpi is NULL");
82 : 0 : return -EINVAL;
83 : : }
84 : :
85 : 0 : pci_dev = roc_dpi->pci_dev;
86 : :
87 : 0 : roc_dpi_disable(roc_dpi);
88 : 0 : rc = roc_dpi_wait_queue_idle(roc_dpi);
89 [ # # ]: 0 : if (rc)
90 : : return rc;
91 : :
92 : 0 : plt_write64(0x0, roc_dpi->rbase + DPI_VDMA_REQQ_CTL);
93 : : plt_write64(chunk_base, roc_dpi->rbase + DPI_VDMA_SADDR);
94 : 0 : mbox_msg.u[0] = 0;
95 : 0 : mbox_msg.u[1] = 0;
96 : : /* DPI PF driver expects vfid starts from index 0 */
97 : 0 : mbox_msg.s.vfid = roc_dpi->vfid;
98 : 0 : mbox_msg.s.pri = roc_dpi->priority;
99 : 0 : mbox_msg.s.cmd = DPI_QUEUE_OPEN;
100 : 0 : mbox_msg.s.csize = chunk_sz;
101 : 0 : mbox_msg.s.aura = aura;
102 : 0 : mbox_msg.s.sso_pf_func = idev_sso_pffunc_get();
103 : 0 : mbox_msg.s.npa_pf_func = idev_npa_pffunc_get();
104 : 0 : mbox_msg.s.wqecsoff = idev_dma_cs_offset_get();
105 [ # # ]: 0 : if (mbox_msg.s.wqecsoff)
106 : 0 : mbox_msg.s.wqecs = 1;
107 : :
108 : 0 : rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg, sizeof(dpi_mbox_msg_t));
109 [ # # ]: 0 : if (rc < 0)
110 : 0 : 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 : 0 : 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 [ # # ]: 0 : if (!roc_dpi) {
123 : 0 : plt_err("roc_dpi is NULL");
124 : 0 : return -EINVAL;
125 : : }
126 : :
127 : 0 : pci_dev = roc_dpi->pci_dev;
128 : :
129 : 0 : roc_dpi_disable(roc_dpi);
130 : :
131 : 0 : rc = roc_dpi_wait_queue_idle(roc_dpi);
132 [ # # ]: 0 : if (rc)
133 : : return rc;
134 : :
135 : 0 : plt_write64(0x0, roc_dpi->rbase + DPI_VDMA_REQQ_CTL);
136 : : plt_write64(chunk_base, roc_dpi->rbase + DPI_VDMA_SADDR);
137 : 0 : mbox_msg.u[0] = 0;
138 : 0 : mbox_msg.u[1] = 0;
139 : : /* DPI PF driver expects vfid starts from index 0 */
140 : 0 : mbox_msg.s.vfid = roc_dpi->vfid;
141 : 0 : mbox_msg.s.pri = roc_dpi->priority;
142 : 0 : mbox_msg.s.cmd = DPI_QUEUE_OPEN_V2;
143 : 0 : mbox_msg.s.csize = chunk_sz / 8;
144 : 0 : mbox_msg.s.aura = aura;
145 : 0 : mbox_msg.s.sso_pf_func = idev_sso_pffunc_get();
146 : 0 : mbox_msg.s.npa_pf_func = idev_npa_pffunc_get();
147 : :
148 : 0 : rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg,
149 : : sizeof(dpi_mbox_msg_t));
150 [ # # ]: 0 : if (rc < 0)
151 : 0 : 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 : 0 : roc_dpi_dev_init(struct roc_dpi *roc_dpi, uint8_t offset)
159 : : {
160 : 0 : struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
161 : : uint16_t vfid;
162 : :
163 : 0 : roc_dpi->rbase = pci_dev->mem_resource[0].addr;
164 : 0 : vfid = ((pci_dev->addr.devid & 0x1F) << 3) | (pci_dev->addr.function & 0x7);
165 : 0 : vfid -= 1;
166 : 0 : roc_dpi->vfid = vfid;
167 : 0 : idev_dma_cs_offset_set(offset);
168 : :
169 : 0 : return 0;
170 : : }
171 : :
172 : : int
173 : 0 : roc_dpi_dev_fini(struct roc_dpi *roc_dpi)
174 : : {
175 : 0 : struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
176 : : dpi_mbox_msg_t mbox_msg;
177 : : int rc;
178 : :
179 : 0 : rc = roc_dpi_wait_queue_idle(roc_dpi);
180 [ # # ]: 0 : if (rc)
181 : : return rc;
182 : :
183 : 0 : mbox_msg.u[0] = 0;
184 : 0 : mbox_msg.u[1] = 0;
185 : 0 : mbox_msg.s.vfid = roc_dpi->vfid;
186 : 0 : mbox_msg.s.cmd = DPI_QUEUE_CLOSE;
187 : :
188 : 0 : rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg, sizeof(dpi_mbox_msg_t));
189 [ # # ]: 0 : if (rc < 0)
190 : 0 : plt_err("Failed to send mbox message %d to DPI PF, err %d", mbox_msg.s.cmd, rc);
191 : :
192 : : return rc;
193 : : }
|