Add functions to operate hardware queue for zsda.
Signed-off-by: Hanxiao Li <li.hanxiao@zte.com.cn>
---
drivers/common/zsda/meson.build | 1 +
drivers/common/zsda/zsda_qp.c | 272 ++++++++++++++++++++++++++++++++
drivers/common/zsda/zsda_qp.h | 15 ++
3 files changed, 288 insertions(+)
create mode 100644 drivers/common/zsda/zsda_qp.c
create mode 100644 drivers/common/zsda/zsda_qp.h
diff --git a/drivers/common/zsda/meson.build b/drivers/common/zsda/meson.build
index 376876f4ed..a4859523e2 100644
--- a/drivers/common/zsda/meson.build
+++ b/drivers/common/zsda/meson.build
@@ -12,4 +12,5 @@ sources += files(
'zsda_logs.c',
'zsda_common.c',
'zsda_device.c',
+ 'zsda_qp.c',
)
diff --git a/drivers/common/zsda/zsda_qp.c b/drivers/common/zsda/zsda_qp.c
new file mode 100644
index 0000000000..95f4ca88d4
--- /dev/null
+++ b/drivers/common/zsda/zsda_qp.c
@@ -0,0 +1,272 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#include <stdint.h>
+
+#include <rte_malloc.h>
+
+#include "zsda_common.h"
+#include "zsda_logs.h"
+#include "zsda_device.h"
+#include "zsda_qp.h"
+
+#define RING_DIR_TX 0
+#define RING_DIR_RX 1
+
+struct ring_size {
+ uint16_t tx_msg_size;
+ uint16_t rx_msg_size;
+};
+uint8_t zsda_num_used_qps;
+
+struct ring_size zsda_qp_hw_ring_size[ZSDA_MAX_SERVICES] = {
+ [ZSDA_SERVICE_SYMMETRIC_ENCRYPT] = {128, 16},
+ [ZSDA_SERVICE_SYMMETRIC_DECRYPT] = {128, 16},
+ [ZSDA_SERVICE_COMPRESSION] = {32, 16},
+ [ZSDA_SERVICE_DECOMPRESSION] = {32, 16},
+ [ZSDA_SERVICE_HASH_ENCODE] = {32, 16},
+};
+
+static void
+zsda_set_queue_head_tail(const struct zsda_pci_device *zsda_pci_dev,
+ const uint8_t qid)
+{
+ struct rte_pci_device *pci_dev =
+ zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+
+ ZSDA_CSR_WRITE32(mmio_base + IO_DB_INITIAL_CONFIG + (qid * 4),
+ SET_HEAD_INTI);
+}
+
+static int
+zsda_get_queue_cfg_by_id(const struct zsda_pci_device *zsda_pci_dev,
+ const uint8_t qid, struct qinfo *qcfg)
+{
+ struct zsda_admin_req_qcfg req = {0};
+ struct zsda_admin_resp_qcfg resp = {0};
+ int ret;
+ struct rte_pci_device *pci_dev =
+ zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;
+
+ if (qid >= MAX_QPS_ON_FUNCTION) {
+ ZSDA_LOG(ERR, "qid beyond limit!");
+ return ZSDA_FAILED;
+ }
+
+ zsda_admin_msg_init(pci_dev);
+ req.msg_type = ZSDA_ADMIN_QUEUE_CFG_REQ;
+ req.qid = qid;
+
+ ret = zsda_send_admin_msg(pci_dev, &req, sizeof(req));
+ if (ret) {
+ ZSDA_LOG(ERR, "Failed! Send msg");
+ return ret;
+ }
+
+ ret = zsda_recv_admin_msg(pci_dev, &resp, sizeof(resp));
+ if (ret) {
+ ZSDA_LOG(ERR, "Failed! Receive msg");
+ return ret;
+ }
+
+ *qcfg = resp.qcfg;
+
+ return ZSDA_SUCCESS;
+}
+
+int
+zsda_get_queue_cfg(struct zsda_pci_device *zsda_pci_dev)
+{
+ uint8_t i;
+ uint32_t index;
+ enum zsda_service_type type;
+ struct zsda_qp_hw *zsda_hw_qps = zsda_pci_dev->zsda_hw_qps;
+ struct qinfo qcfg = {0};
+ int ret;
+
+ for (i = 0; i < zsda_num_used_qps; i++) {
+ zsda_set_queue_head_tail(zsda_pci_dev, i);
+ ret = zsda_get_queue_cfg_by_id(zsda_pci_dev, i, &qcfg);
+ type = qcfg.q_type;
+ if (ret) {
+ ZSDA_LOG(ERR, "get queue cfg!");
+ return ret;
+ }
+ if (type >= ZSDA_SERVICE_INVALID)
+ continue;
+
+ index = zsda_pci_dev->zsda_qp_hw_num[type];
+ zsda_hw_qps[type].data[index].used = true;
+ zsda_hw_qps[type].data[index].tx_ring_num = i;
+ zsda_hw_qps[type].data[index].rx_ring_num = i;
+ zsda_hw_qps[type].data[index].tx_msg_size =
+ zsda_qp_hw_ring_size[type].tx_msg_size;
+ zsda_hw_qps[type].data[index].rx_msg_size =
+ zsda_qp_hw_ring_size[type].rx_msg_size;
+
+ zsda_pci_dev->zsda_qp_hw_num[type]++;
+ }
+
+ return ret;
+}
+
+static uint8_t
+zsda_get_num_used_qps(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ uint8_t num_used_qps;
+
+ num_used_qps = ZSDA_CSR_READ8(mmio_base + 0);
+
+ return num_used_qps;
+}
+
+static int
+zsda_check_write(uint8_t *addr, const uint32_t dst_value)
+{
+ int times = ZSDA_TIME_NUM;
+ uint32_t val;
+
+ val = ZSDA_CSR_READ32(addr);
+
+ while ((val != dst_value) && times--) {
+ val = ZSDA_CSR_READ32(addr);
+ rte_delay_us_sleep(ZSDA_TIME_SLEEP_US);
+ }
+ if (val == dst_value)
+ return ZSDA_SUCCESS;
+ else
+ return ZSDA_FAILED;
+}
+
+static int
+zsda_admin_q_start(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ int ret;
+
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, 0);
+
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);
+ ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);
+
+ return ret;
+}
+
+static int
+zsda_admin_q_stop(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ int ret;
+
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP_RESP, ZSDA_RESP_INVALID);
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP, ZSDA_Q_STOP);
+
+ ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_STOP_RESP,
+ ZSDA_RESP_VALID);
+
+ if (ret)
+ ZSDA_LOG(INFO, "Failed! zsda_admin q stop");
+
+ return ret;
+}
+
+static int
+zsda_admin_q_clear(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ int ret;
+
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR_RESP, ZSDA_RESP_INVALID);
+ ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR, ZSDA_RESP_VALID);
+
+ ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_CLR_RESP,
+ ZSDA_RESP_VALID);
+
+ if (ret)
+ ZSDA_LOG(INFO, "Failed! zsda_admin q clear");
+
+ return ret;
+}
+
+static int
+zsda_queue_start_single(uint8_t *mmio_base, const uint8_t id)
+{
+ uint8_t *addr_start = mmio_base + ZSDA_IO_Q_START + (4 * id);
+
+ ZSDA_CSR_WRITE32(addr_start, ZSDA_Q_START);
+ return zsda_check_write(addr_start, ZSDA_Q_START);
+}
+
+
+static int
+zsda_queue_stop_single(uint8_t *mmio_base, const uint8_t id)
+{
+ int ret;
+ uint8_t *addr_stop = mmio_base + ZSDA_IO_Q_STOP + (4 * id);
+ uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_STOP_RESP + (4 * id);
+
+ ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
+ ZSDA_CSR_WRITE32(addr_stop, ZSDA_Q_STOP);
+
+ ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);
+ ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
+
+ return ret;
+}
+
+static int
+zsda_queue_clear_single(uint8_t *mmio_base, const uint8_t id)
+{
+ int ret;
+ uint8_t *addr_clear = mmio_base + ZSDA_IO_Q_CLR + (4 * id);
+ uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_CLR_RESP + (4 * id);
+
+ ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
+ ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_VALID);
+ ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);
+ ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_INVALID);
+
+ return ret;
+}
+
+int
+zsda_queue_start(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ uint8_t id;
+ int ret = ZSDA_SUCCESS;
+
+ for (id = 0; id < zsda_num_used_qps; id++)
+ ret |= zsda_queue_start_single(mmio_base, id);
+
+ return ret;
+}
+
+int
+zsda_queue_stop(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ uint8_t id;
+ int ret = ZSDA_SUCCESS;
+
+ for (id = 0; id < zsda_num_used_qps; id++)
+ ret |= zsda_queue_stop_single(mmio_base, id);
+
+ return ret;
+}
+
+static int
+zsda_queue_clear(const struct rte_pci_device *pci_dev)
+{
+ uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
+ uint8_t id;
+ int ret = ZSDA_SUCCESS;
+
+ for (id = 0; id < zsda_num_used_qps; id++)
+ ret |= zsda_queue_clear_single(mmio_base, id);
+
+ return ret;
+}
diff --git a/drivers/common/zsda/zsda_qp.h b/drivers/common/zsda/zsda_qp.h
new file mode 100644
index 0000000000..00b1137ba3
--- /dev/null
+++ b/drivers/common/zsda/zsda_qp.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#ifndef _ZSDA_QP_H_
+#define _ZSDA_QP_H_
+
+int zsda_queue_start(const struct rte_pci_device *pci_dev);
+int zsda_queue_stop(const struct rte_pci_device *pci_dev);
+
+int zsda_queue_init(struct zsda_pci_device *zsda_pci_dev);
+
+int zsda_get_queue_cfg(struct zsda_pci_device *zsda_pci_dev);
+
+#endif /* _ZSDA_QP_H_ */
--
2.27.0