1 // SPDX-License-Identifier: GPL-2.0-only
3 * SolidRun DPU driver for control plane
5 * Copyright (C) 2022-2023 SolidRun
7 * Author: Alvaro Karsz <alvaro.karsz@solid-run.com>
11 #include <linux/iopoll.h>
13 #include "snet_vdpa.h"
15 enum snet_ctrl_opcodes
{
16 SNET_CTRL_OP_DESTROY
= 1,
17 SNET_CTRL_OP_READ_VQ_STATE
,
22 #define SNET_CTRL_TIMEOUT 2000000
24 #define SNET_CTRL_DATA_SIZE_MASK 0x0000FFFF
25 #define SNET_CTRL_IN_PROCESS_MASK 0x00010000
26 #define SNET_CTRL_CHUNK_RDY_MASK 0x00020000
27 #define SNET_CTRL_ERROR_MASK 0x0FFC0000
29 #define SNET_VAL_TO_ERR(val) (-(((val) & SNET_CTRL_ERROR_MASK) >> 18))
30 #define SNET_EMPTY_CTRL(val) (((val) & SNET_CTRL_ERROR_MASK) || \
31 !((val) & SNET_CTRL_IN_PROCESS_MASK))
32 #define SNET_DATA_READY(val) ((val) & (SNET_CTRL_ERROR_MASK | SNET_CTRL_CHUNK_RDY_MASK))
34 /* Control register used to read data from the DPU */
35 struct snet_ctrl_reg_ctrl
{
36 /* Chunk size in 4B words */
38 /* We are in the middle of a command */
40 /* A data chunk is ready and can be consumed */
44 /* Saved for future usage */
49 struct snet_ctrl_reg_op
{
51 /* Only if VQ index is relevant for the command */
55 struct snet_ctrl_regs
{
56 struct snet_ctrl_reg_op op
;
57 struct snet_ctrl_reg_ctrl ctrl
;
62 static struct snet_ctrl_regs __iomem
*snet_get_ctrl(struct snet
*snet
)
64 return snet
->bar
+ snet
->psnet
->cfg
.ctrl_off
;
67 static int snet_wait_for_empty_ctrl(struct snet_ctrl_regs __iomem
*regs
)
71 return readx_poll_timeout(ioread32
, ®s
->ctrl
, val
, SNET_EMPTY_CTRL(val
), 10,
75 static int snet_wait_for_empty_op(struct snet_ctrl_regs __iomem
*regs
)
79 return readx_poll_timeout(ioread32
, ®s
->op
, val
, !val
, 10, SNET_CTRL_TIMEOUT
);
82 static int snet_wait_for_data(struct snet_ctrl_regs __iomem
*regs
)
86 return readx_poll_timeout(ioread32
, ®s
->ctrl
, val
, SNET_DATA_READY(val
), 10,
90 static u32
snet_read32_word(struct snet_ctrl_regs __iomem
*ctrl_regs
, u16 word_idx
)
92 return ioread32(&ctrl_regs
->data
[word_idx
]);
95 static u32
snet_read_ctrl(struct snet_ctrl_regs __iomem
*ctrl_regs
)
97 return ioread32(&ctrl_regs
->ctrl
);
100 static void snet_write_ctrl(struct snet_ctrl_regs __iomem
*ctrl_regs
, u32 val
)
102 iowrite32(val
, &ctrl_regs
->ctrl
);
105 static void snet_write_op(struct snet_ctrl_regs __iomem
*ctrl_regs
, u32 val
)
107 iowrite32(val
, &ctrl_regs
->op
);
110 static int snet_wait_for_dpu_completion(struct snet_ctrl_regs __iomem
*ctrl_regs
)
112 /* Wait until the DPU finishes completely.
113 * It will clear the opcode register.
115 return snet_wait_for_empty_op(ctrl_regs
);
118 /* Reading ctrl from the DPU:
119 * buf_size must be 4B aligned
123 * (1) Verify that the DPU is not in the middle of another operation by
124 * reading the in_process and error bits in the control register.
125 * (2) Write the request opcode and the VQ idx in the opcode register
126 * and write the buffer size in the control register.
127 * (3) Start readind chunks of data, chunk_ready bit indicates that a
128 * data chunk is available, we signal that we read the data by clearing the bit.
129 * (4) Detect that the transfer is completed when the in_process bit
130 * in the control register is cleared or when the an error appears.
132 static int snet_ctrl_read_from_dpu(struct snet
*snet
, u16 opcode
, u16 vq_idx
, void *buffer
,
135 struct pci_dev
*pdev
= snet
->pdev
;
136 struct snet_ctrl_regs __iomem
*regs
= snet_get_ctrl(snet
);
137 u32
*bfr_ptr
= (u32
*)buffer
;
141 u16 words
, i
, tot_words
= 0;
143 /* Supported for config 2+ */
144 if (!SNET_CFG_VER(snet
, 2))
147 if (!IS_ALIGNED(buf_size
, 4))
150 mutex_lock(&snet
->ctrl_lock
);
152 buf_words
= buf_size
/ 4;
154 /* Make sure control register is empty */
155 ret
= snet_wait_for_empty_ctrl(regs
);
157 SNET_WARN(pdev
, "Timeout waiting for previous control data to be consumed\n");
161 /* We need to write the buffer size in the control register, and the opcode + vq index in
162 * the opcode register.
163 * We use a spinlock to serialize the writes.
165 spin_lock(&snet
->ctrl_spinlock
);
167 snet_write_ctrl(regs
, buf_words
);
168 snet_write_op(regs
, opcode
| (vq_idx
<< 16));
170 spin_unlock(&snet
->ctrl_spinlock
);
172 while (buf_words
!= tot_words
) {
173 ret
= snet_wait_for_data(regs
);
175 SNET_WARN(pdev
, "Timeout waiting for control data\n");
179 val
= snet_read_ctrl(regs
);
182 if (val
& SNET_CTRL_ERROR_MASK
) {
183 ret
= SNET_VAL_TO_ERR(val
);
184 SNET_WARN(pdev
, "Error while reading control data from DPU, err %d\n", ret
);
188 words
= min_t(u16
, val
& SNET_CTRL_DATA_SIZE_MASK
, buf_words
- tot_words
);
190 for (i
= 0; i
< words
; i
++) {
191 *bfr_ptr
= snet_read32_word(regs
, i
);
197 /* Is the job completed? */
198 if (!(val
& SNET_CTRL_IN_PROCESS_MASK
))
201 /* Clear the chunk ready bit and continue */
202 val
&= ~SNET_CTRL_CHUNK_RDY_MASK
;
203 snet_write_ctrl(regs
, val
);
206 ret
= snet_wait_for_dpu_completion(regs
);
208 SNET_WARN(pdev
, "Timeout waiting for the DPU to complete a control command\n");
211 mutex_unlock(&snet
->ctrl_lock
);
215 /* Send a control message to the DPU using the old mechanism
216 * used with config version 1.
218 static int snet_send_ctrl_msg_old(struct snet
*snet
, u32 opcode
)
220 struct pci_dev
*pdev
= snet
->pdev
;
221 struct snet_ctrl_regs __iomem
*regs
= snet_get_ctrl(snet
);
224 mutex_lock(&snet
->ctrl_lock
);
226 /* Old mechanism uses just 1 register, the opcode register.
227 * Make sure that the opcode register is empty, and that the DPU isn't
228 * processing an old message.
230 ret
= snet_wait_for_empty_op(regs
);
232 SNET_WARN(pdev
, "Timeout waiting for previous control message to be ACKed\n");
236 /* Write the message */
237 snet_write_op(regs
, opcode
);
239 /* DPU ACKs the message by clearing the opcode register */
240 ret
= snet_wait_for_empty_op(regs
);
242 SNET_WARN(pdev
, "Timeout waiting for a control message to be ACKed\n");
245 mutex_unlock(&snet
->ctrl_lock
);
249 /* Send a control message to the DPU.
250 * A control message is a message without payload.
252 static int snet_send_ctrl_msg(struct snet
*snet
, u16 opcode
, u16 vq_idx
)
254 struct pci_dev
*pdev
= snet
->pdev
;
255 struct snet_ctrl_regs __iomem
*regs
= snet_get_ctrl(snet
);
259 /* If config version is not 2+, use the old mechanism */
260 if (!SNET_CFG_VER(snet
, 2))
261 return snet_send_ctrl_msg_old(snet
, opcode
);
263 mutex_lock(&snet
->ctrl_lock
);
265 /* Make sure control register is empty */
266 ret
= snet_wait_for_empty_ctrl(regs
);
268 SNET_WARN(pdev
, "Timeout waiting for previous control data to be consumed\n");
272 /* We need to clear the control register and write the opcode + vq index in the opcode
274 * We use a spinlock to serialize the writes.
276 spin_lock(&snet
->ctrl_spinlock
);
278 snet_write_ctrl(regs
, 0);
279 snet_write_op(regs
, opcode
| (vq_idx
<< 16));
281 spin_unlock(&snet
->ctrl_spinlock
);
283 /* The DPU ACKs control messages by setting the chunk ready bit
286 ret
= snet_wait_for_data(regs
);
288 SNET_WARN(pdev
, "Timeout waiting for control message to be ACKed\n");
292 /* Check for errors */
293 val
= snet_read_ctrl(regs
);
294 ret
= SNET_VAL_TO_ERR(val
);
296 /* Clear the chunk ready bit */
297 val
&= ~SNET_CTRL_CHUNK_RDY_MASK
;
298 snet_write_ctrl(regs
, val
);
300 ret
= snet_wait_for_dpu_completion(regs
);
302 SNET_WARN(pdev
, "Timeout waiting for DPU to complete a control command, err %d\n",
306 mutex_unlock(&snet
->ctrl_lock
);
310 void snet_ctrl_clear(struct snet
*snet
)
312 struct snet_ctrl_regs __iomem
*regs
= snet_get_ctrl(snet
);
314 snet_write_op(regs
, 0);
317 int snet_destroy_dev(struct snet
*snet
)
319 return snet_send_ctrl_msg(snet
, SNET_CTRL_OP_DESTROY
, 0);
322 int snet_read_vq_state(struct snet
*snet
, u16 idx
, struct vdpa_vq_state
*state
)
324 return snet_ctrl_read_from_dpu(snet
, SNET_CTRL_OP_READ_VQ_STATE
, idx
, state
,
328 int snet_suspend_dev(struct snet
*snet
)
330 return snet_send_ctrl_msg(snet
, SNET_CTRL_OP_SUSPEND
, 0);
333 int snet_resume_dev(struct snet
*snet
)
335 return snet_send_ctrl_msg(snet
, SNET_CTRL_OP_RESUME
, 0);