Re: [PATCH v4 1/2] vdpa/snet: support getting and setting VQ state

2023-04-17 Thread Alvaro Karsz
> > Signed-off-by: Alvaro Karsz 
> 
> Acked-by: Jason Wang 
> 

Thanks Jason.

BTW, Michael, I see that you merged the first version into the mst tree.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v4 1/2] vdpa/snet: support getting and setting VQ state

2023-04-17 Thread Jason Wang
On Thu, Apr 13, 2023 at 3:33 PM Alvaro Karsz  wrote:
>
> This patch adds the get_vq_state and set_vq_state vDPA callbacks.
>
> In order to get the VQ state, the state needs to be read from the DPU.
> In order to allow that, the old messaging mechanism is replaced with a new,
> flexible control mechanism.
> This mechanism allows to read data from the DPU.
>
> The mechanism can be used if the negotiated config version is 2 or
> higher.
>
> If the new mechanism is used when the config version is 1, it will call
> snet_send_ctrl_msg_old, which is config 1 compatible.
>
> Signed-off-by: Alvaro Karsz 

Acked-by: Jason Wang 

Thanks

> ---
>  drivers/vdpa/solidrun/Makefile |   1 +
>  drivers/vdpa/solidrun/snet_ctrl.c  | 324 +
>  drivers/vdpa/solidrun/snet_hwmon.c |   2 +-
>  drivers/vdpa/solidrun/snet_main.c  | 112 --
>  drivers/vdpa/solidrun/snet_vdpa.h  |  19 +-
>  5 files changed, 387 insertions(+), 71 deletions(-)
>  create mode 100644 drivers/vdpa/solidrun/snet_ctrl.c
>
> diff --git a/drivers/vdpa/solidrun/Makefile b/drivers/vdpa/solidrun/Makefile
> index c0aa3415bf7..9116252cd5f 100644
> --- a/drivers/vdpa/solidrun/Makefile
> +++ b/drivers/vdpa/solidrun/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_SNET_VDPA) += snet_vdpa.o
>  snet_vdpa-$(CONFIG_SNET_VDPA) += snet_main.o
> +snet_vdpa-$(CONFIG_SNET_VDPA) += snet_ctrl.o
>  ifdef CONFIG_HWMON
>  snet_vdpa-$(CONFIG_SNET_VDPA) += snet_hwmon.o
>  endif
> diff --git a/drivers/vdpa/solidrun/snet_ctrl.c 
> b/drivers/vdpa/solidrun/snet_ctrl.c
> new file mode 100644
> index 000..10cde502f1a
> --- /dev/null
> +++ b/drivers/vdpa/solidrun/snet_ctrl.c
> @@ -0,0 +1,324 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * SolidRun DPU driver for control plane
> + *
> + * Copyright (C) 2022-2023 SolidRun
> + *
> + * Author: Alvaro Karsz 
> + *
> + */
> +
> +#include 
> +
> +#include "snet_vdpa.h"
> +
> +enum snet_ctrl_opcodes {
> +   SNET_CTRL_OP_DESTROY = 1,
> +   SNET_CTRL_OP_READ_VQ_STATE,
> +};
> +
> +#define SNET_CTRL_TIMEOUT  200
> +
> +#define SNET_CTRL_DATA_SIZE_MASK   0x
> +#define SNET_CTRL_IN_PROCESS_MASK  0x0001
> +#define SNET_CTRL_CHUNK_RDY_MASK   0x0002
> +#define SNET_CTRL_ERROR_MASK   0x0FFC
> +
> +#define SNET_VAL_TO_ERR(val)   (-(((val) & SNET_CTRL_ERROR_MASK) >> 
> 18))
> +#define SNET_EMPTY_CTRL(val)   (((val) & SNET_CTRL_ERROR_MASK) || \
> +   !((val) & 
> SNET_CTRL_IN_PROCESS_MASK))
> +#define SNET_DATA_READY(val)   ((val) & (SNET_CTRL_ERROR_MASK | 
> SNET_CTRL_CHUNK_RDY_MASK))
> +
> +/* Control register used to read data from the DPU */
> +struct snet_ctrl_reg_ctrl {
> +   /* Chunk size in 4B words */
> +   u16 data_size;
> +   /* We are in the middle of a command */
> +   u16 in_process:1;
> +   /* A data chunk is ready and can be consumed */
> +   u16 chunk_ready:1;
> +   /* Error code */
> +   u16 error:10;
> +   /* Saved for future usage */
> +   u16 rsvd:4;
> +};
> +
> +/* Opcode register */
> +struct snet_ctrl_reg_op {
> +   u16 opcode;
> +   /* Only if VQ index is relevant for the command */
> +   u16 vq_idx;
> +};
> +
> +struct snet_ctrl_regs {
> +   struct snet_ctrl_reg_op op;
> +   struct snet_ctrl_reg_ctrl ctrl;
> +   u32 rsvd;
> +   u32 data[];
> +};
> +
> +static struct snet_ctrl_regs __iomem *snet_get_ctrl(struct snet *snet)
> +{
> +   return snet->bar + snet->psnet->cfg.ctrl_off;
> +}
> +
> +static int snet_wait_for_empty_ctrl(struct snet_ctrl_regs __iomem *regs)
> +{
> +   u32 val;
> +
> +   return readx_poll_timeout(ioread32, >ctrl, val, 
> SNET_EMPTY_CTRL(val), 10,
> + SNET_CTRL_TIMEOUT);
> +}
> +
> +static int snet_wait_for_empty_op(struct snet_ctrl_regs __iomem *regs)
> +{
> +   u32 val;
> +
> +   return readx_poll_timeout(ioread32, >op, val, !val, 10, 
> SNET_CTRL_TIMEOUT);
> +}
> +
> +static int snet_wait_for_data(struct snet_ctrl_regs __iomem *regs)
> +{
> +   u32 val;
> +
> +   return readx_poll_timeout(ioread32, >ctrl, val, 
> SNET_DATA_READY(val), 10,
> + SNET_CTRL_TIMEOUT);
> +}
> +
> +static u32 snet_read32_word(struct snet_ctrl_regs __iomem *ctrl_regs, u16 
> word_idx)
> +{
> +   return ioread32(_regs->data[word_idx]);
> +}
> +
> +static u32 snet_read_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs)
> +{
> +   return ioread32(_regs->ctrl);
> +}
> +
> +static void snet_write_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs, u32 
> val)
> +{
> +   iowrite32(val, _regs->ctrl);
> +}
> +
> +static void snet_write_op(struct snet_ctrl_regs __iomem *ctrl_regs, u32 val)
> +{
> +   iowrite32(val, _regs->op);
> +}
> +
> +static int snet_wait_for_dpu_completion(struct snet_ctrl_regs __iomem 
> *ctrl_regs)
> +{
> +   /* Wait until the DPU 

[PATCH v4 1/2] vdpa/snet: support getting and setting VQ state

2023-04-13 Thread Alvaro Karsz
This patch adds the get_vq_state and set_vq_state vDPA callbacks.

In order to get the VQ state, the state needs to be read from the DPU.
In order to allow that, the old messaging mechanism is replaced with a new,
flexible control mechanism.
This mechanism allows to read data from the DPU.

The mechanism can be used if the negotiated config version is 2 or
higher.

If the new mechanism is used when the config version is 1, it will call
snet_send_ctrl_msg_old, which is config 1 compatible.

Signed-off-by: Alvaro Karsz 
---
 drivers/vdpa/solidrun/Makefile |   1 +
 drivers/vdpa/solidrun/snet_ctrl.c  | 324 +
 drivers/vdpa/solidrun/snet_hwmon.c |   2 +-
 drivers/vdpa/solidrun/snet_main.c  | 112 --
 drivers/vdpa/solidrun/snet_vdpa.h  |  19 +-
 5 files changed, 387 insertions(+), 71 deletions(-)
 create mode 100644 drivers/vdpa/solidrun/snet_ctrl.c

diff --git a/drivers/vdpa/solidrun/Makefile b/drivers/vdpa/solidrun/Makefile
index c0aa3415bf7..9116252cd5f 100644
--- a/drivers/vdpa/solidrun/Makefile
+++ b/drivers/vdpa/solidrun/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_SNET_VDPA) += snet_vdpa.o
 snet_vdpa-$(CONFIG_SNET_VDPA) += snet_main.o
+snet_vdpa-$(CONFIG_SNET_VDPA) += snet_ctrl.o
 ifdef CONFIG_HWMON
 snet_vdpa-$(CONFIG_SNET_VDPA) += snet_hwmon.o
 endif
diff --git a/drivers/vdpa/solidrun/snet_ctrl.c 
b/drivers/vdpa/solidrun/snet_ctrl.c
new file mode 100644
index 000..10cde502f1a
--- /dev/null
+++ b/drivers/vdpa/solidrun/snet_ctrl.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SolidRun DPU driver for control plane
+ *
+ * Copyright (C) 2022-2023 SolidRun
+ *
+ * Author: Alvaro Karsz 
+ *
+ */
+
+#include 
+
+#include "snet_vdpa.h"
+
+enum snet_ctrl_opcodes {
+   SNET_CTRL_OP_DESTROY = 1,
+   SNET_CTRL_OP_READ_VQ_STATE,
+};
+
+#define SNET_CTRL_TIMEOUT  200
+
+#define SNET_CTRL_DATA_SIZE_MASK   0x
+#define SNET_CTRL_IN_PROCESS_MASK  0x0001
+#define SNET_CTRL_CHUNK_RDY_MASK   0x0002
+#define SNET_CTRL_ERROR_MASK   0x0FFC
+
+#define SNET_VAL_TO_ERR(val)   (-(((val) & SNET_CTRL_ERROR_MASK) >> 
18))
+#define SNET_EMPTY_CTRL(val)   (((val) & SNET_CTRL_ERROR_MASK) || \
+   !((val) & 
SNET_CTRL_IN_PROCESS_MASK))
+#define SNET_DATA_READY(val)   ((val) & (SNET_CTRL_ERROR_MASK | 
SNET_CTRL_CHUNK_RDY_MASK))
+
+/* Control register used to read data from the DPU */
+struct snet_ctrl_reg_ctrl {
+   /* Chunk size in 4B words */
+   u16 data_size;
+   /* We are in the middle of a command */
+   u16 in_process:1;
+   /* A data chunk is ready and can be consumed */
+   u16 chunk_ready:1;
+   /* Error code */
+   u16 error:10;
+   /* Saved for future usage */
+   u16 rsvd:4;
+};
+
+/* Opcode register */
+struct snet_ctrl_reg_op {
+   u16 opcode;
+   /* Only if VQ index is relevant for the command */
+   u16 vq_idx;
+};
+
+struct snet_ctrl_regs {
+   struct snet_ctrl_reg_op op;
+   struct snet_ctrl_reg_ctrl ctrl;
+   u32 rsvd;
+   u32 data[];
+};
+
+static struct snet_ctrl_regs __iomem *snet_get_ctrl(struct snet *snet)
+{
+   return snet->bar + snet->psnet->cfg.ctrl_off;
+}
+
+static int snet_wait_for_empty_ctrl(struct snet_ctrl_regs __iomem *regs)
+{
+   u32 val;
+
+   return readx_poll_timeout(ioread32, >ctrl, val, 
SNET_EMPTY_CTRL(val), 10,
+ SNET_CTRL_TIMEOUT);
+}
+
+static int snet_wait_for_empty_op(struct snet_ctrl_regs __iomem *regs)
+{
+   u32 val;
+
+   return readx_poll_timeout(ioread32, >op, val, !val, 10, 
SNET_CTRL_TIMEOUT);
+}
+
+static int snet_wait_for_data(struct snet_ctrl_regs __iomem *regs)
+{
+   u32 val;
+
+   return readx_poll_timeout(ioread32, >ctrl, val, 
SNET_DATA_READY(val), 10,
+ SNET_CTRL_TIMEOUT);
+}
+
+static u32 snet_read32_word(struct snet_ctrl_regs __iomem *ctrl_regs, u16 
word_idx)
+{
+   return ioread32(_regs->data[word_idx]);
+}
+
+static u32 snet_read_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs)
+{
+   return ioread32(_regs->ctrl);
+}
+
+static void snet_write_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs, u32 val)
+{
+   iowrite32(val, _regs->ctrl);
+}
+
+static void snet_write_op(struct snet_ctrl_regs __iomem *ctrl_regs, u32 val)
+{
+   iowrite32(val, _regs->op);
+}
+
+static int snet_wait_for_dpu_completion(struct snet_ctrl_regs __iomem 
*ctrl_regs)
+{
+   /* Wait until the DPU finishes completely.
+* It will clear the opcode register.
+*/
+   return snet_wait_for_empty_op(ctrl_regs);
+}
+
+/* Reading ctrl from the DPU:
+ * buf_size must be 4B aligned
+ *
+ * Steps:
+ *
+ * (1) Verify that the DPU is not in the middle of another operation by
+ * reading the in_process and error bits in the control register.
+ * (2) Write the request opcode and the VQ idx in