@@ -12,6 +12,7 @@ sources = files(
'xsc_utils.c',
'xsc_ctrl.c',
'xsc_rxtx.c',
+ 'xsc_flow.c',
)
libnames = ['ibverbs']
@@ -41,6 +41,12 @@ enum xsc_ioctl_opmod {
((_n) + (_d) - 1) / (_d); \
})
+enum {
+ XSC_CMD_OP_MODIFY_RAW_QP = 0x81f,
+ XSC_CMD_OP_IOCTL_FLOW = 0x900,
+ XSC_CMD_OP_MAX
+};
+
enum {
XSC_IOCTL_SET_QP_STATUS = 0x200,
XSC_IOCTL_SET_MAX
@@ -72,6 +78,22 @@ enum {
XSC_QUEUE_TYPE_RAW_TX = 7,
XSC_QUEUE_TYPE_INVALID = 0xFF,
};
+enum xsc_flow_tbl_id {
+ XSC_FLOW_TBL_IPAT = 0,
+ XSC_FLOW_TBL_PCT_V4 = 4,
+ XSC_FLOW_TBL_EPAT = 19,
+ XSC_FLOW_TBL_MAX
+};
+
+enum xsc_ioctl_op {
+ XSC_IOCTL_OP_ADD,
+ XSC_IOCTL_OP_DEL,
+ XSC_IOCTL_OP_GET,
+ XSC_IOCTL_OP_CLR,
+ XSC_IOCTL_OP_MOD,
+ XSC_IOCTL_OP_MAX
+};
+
struct xsc_inbox_hdr {
__be16 opcode;
@@ -11,6 +11,7 @@
#include "xsc_dev.h"
#include "xsc_ethdev.h"
#include "xsc_utils.h"
+#include "xsc_flow.h"
#include "xsc_ctrl.h"
#include "xsc_rxtx.h"
@@ -787,6 +788,43 @@ xsc_rxq_start(struct rte_eth_dev *dev)
return -rte_errno;
}
+static int
+xsc_dev_start_config_hw(struct rte_eth_dev *dev)
+{
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+ struct xsc_hwinfo *hwinfo;
+ int peer_dstinfo = 0;
+ int peer_logicalport = 0;
+ int logical_port = 0;
+ int local_dstinfo = 0;
+ int pcie_logic_port = 0;
+ int qp_set_id = 0;
+ int rep_id;
+ struct xsc_rxq_data *rxq = xsc_rxq_get(dev, 0);
+ uint16_t rx_qpn = (uint16_t)rxq->qpn;
+ static int xsc_global_pct_priority_idx = 128;
+
+ if (priv->funcid_type != XSC_PHYPORT_MAC_FUNCID)
+ return -1;
+
+ hwinfo = &priv->xdev->hwinfo;
+ rep_id = priv->representor_id;
+ peer_dstinfo = hwinfo->mac_phy_port;
+ peer_logicalport = hwinfo->mac_phy_port;
+
+ qp_set_id = rep_id % 511 + 1;
+ logical_port = priv->xdev->vfos_logical_in_port + qp_set_id - 1;
+ local_dstinfo = logical_port;
+ pcie_logic_port = hwinfo->pcie_no + 8;
+
+ xsc_create_ipat(dev, logical_port, peer_dstinfo);
+ xsc_create_epat(dev, local_dstinfo, pcie_logic_port,
+ rx_qpn - hwinfo->raw_rss_qp_id_base, priv->num_rq);
+ xsc_create_pct(dev, logical_port, peer_dstinfo, xsc_global_pct_priority_idx++);
+ xsc_create_pct(dev, peer_logicalport, local_dstinfo, xsc_global_pct_priority_idx++);
+ return 0;
+}
+
static int
xsc_ethdev_start(struct rte_eth_dev *dev)
{
@@ -812,6 +850,7 @@ xsc_ethdev_start(struct rte_eth_dev *dev)
dev->rx_pkt_burst = xsc_rx_burst;
dev->tx_pkt_burst = xsc_tx_burst;
+ ret = xsc_dev_start_config_hw(dev);
return 0;
error:
new file mode 100644
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 Yunsilicon Technology Co., Ltd.
+ */
+
+#include <ethdev_pci.h>
+#include <rte_kvargs.h>
+
+#include "xsc_log.h"
+#include "xsc_defs.h"
+#include "xsc_dev.h"
+#include "xsc_ethdev.h"
+#include "xsc_utils.h"
+#include "xsc_flow.h"
+#include "xsc_ctrl.h"
+
+
+static int
+xsc_flow_exec(struct xsc_dev *dev, void *cmd, int len, int table, int opmod)
+{
+ struct xsc_ioctl_data_tl *tl;
+ struct xsc_ioctl_mbox_in *in;
+ struct xsc_ioctl_mbox_out *out;
+ int in_len;
+ int out_len;
+ int data_len;
+ int cmd_len;
+ int ret;
+
+ data_len = sizeof(struct xsc_ioctl_data_tl) + len;
+ in_len = sizeof(struct xsc_ioctl_mbox_in) + data_len;
+ out_len = sizeof(struct xsc_ioctl_mbox_out) + data_len;
+ cmd_len = RTE_MAX(in_len, out_len);
+ in = rte_zmalloc(NULL, cmd_len, RTE_CACHE_LINE_SIZE);
+ if (in == NULL) {
+ rte_errno = ENOMEM;
+ PMD_DRV_LOG(ERR, "alloc flow ioctl cmd memory failed\n");
+ return -rte_errno;
+ }
+
+ in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_IOCTL_FLOW);
+ in->len = rte_cpu_to_be_16(data_len);
+
+ tl = (struct xsc_ioctl_data_tl *)in->data;
+ tl->length = len;
+ tl->table = table;
+ tl->opmod = opmod;
+ if (cmd && len)
+ rte_memcpy(tl + 1, cmd, len);
+
+ out = (struct xsc_ioctl_mbox_out *)in;
+ ret = xsc_mailbox_exec(dev, in, in_len, out, out_len);
+
+ rte_free(in);
+ return ret;
+}
+
+int
+xsc_create_pct(struct rte_eth_dev *dev, uint16_t logical_in_port,
+ uint16_t dst_info, uint32_t priority)
+{
+ struct xsc_flow_pct_v4_add {
+ struct xsc_pct_v4_key key;
+ struct xsc_pct_v4_key mask;
+ struct xsc_pct_action action;
+ uint32_t priority;
+ } add;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&add, 0, sizeof(add));
+
+
+ add.key.logical_in_port = logical_in_port & 0x07FF;
+ add.mask.logical_in_port = 0x07FF;
+ add.action.dst_info = dst_info;
+ add.priority = priority;
+ return xsc_flow_exec(priv->xdev, &add, sizeof(add),
+ XSC_FLOW_TBL_PCT_V4, XSC_IOCTL_OP_ADD);
+}
+
+int
+xsc_destroy_pct(struct rte_eth_dev *dev, uint16_t logical_in_port, uint32_t priority)
+{
+ struct xsc_flow_pct_v4_add {
+ struct xsc_pct_v4_key key;
+ struct xsc_pct_v4_key mask;
+ uint32_t priority;
+ } del;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&del, 0, sizeof(del));
+
+ del.key.logical_in_port = logical_in_port & 0x07FF;
+ del.mask.logical_in_port = 0x07FF;
+ del.priority = priority;
+ return xsc_flow_exec(priv->xdev, &del, sizeof(del),
+ XSC_FLOW_TBL_PCT_V4, XSC_IOCTL_OP_DEL);
+}
+
+int
+xsc_create_ipat(struct rte_eth_dev *dev, uint16_t logic_in_port, uint16_t dst_info)
+{
+ struct xsc_flow_ipat_add {
+ struct xsc_ipat_key key;
+ struct xsc_ipat_action action;
+ } add;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&add, 0, sizeof(add));
+
+ add.key.logical_in_port = logic_in_port;
+ add.action.dst_info = dst_info;
+ add.action.vld = 1;
+ return xsc_flow_exec(priv->xdev, &add, sizeof(add),
+ XSC_FLOW_TBL_IPAT, XSC_IOCTL_OP_ADD);
+}
+
+int
+xsc_destroy_ipat(struct rte_eth_dev *dev, uint16_t logic_in_port)
+{
+ struct xsc_flow_ipat_del {
+ struct xsc_ipat_key key;
+ } del;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&del, 0, sizeof(del));
+
+ del.key.logical_in_port = logic_in_port;
+ return xsc_flow_exec(priv->xdev, &del, sizeof(del),
+ XSC_FLOW_TBL_IPAT, XSC_IOCTL_OP_DEL);
+}
+
+int
+xsc_create_epat(struct rte_eth_dev *dev, uint16_t dst_info, uint8_t dst_port,
+ uint16_t qpn_ofst, uint8_t qp_num)
+{
+ struct xsc_flow_epat_add {
+ struct xsc_epat_key key;
+ struct xsc_epat_action action;
+ } add;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&add, 0, sizeof(add));
+ add.key.dst_info = dst_info;
+ add.action.dst_port = dst_port;
+ add.action.vld = 1;
+ add.action.rx_qp_id_ofst = qpn_ofst;
+ add.action.qp_num = qp_num - 1;
+
+ return xsc_flow_exec(priv->xdev, &add, sizeof(add),
+ XSC_FLOW_TBL_EPAT, XSC_IOCTL_OP_ADD);
+}
+
+int
+xsc_destroy_epat(struct rte_eth_dev *dev, uint16_t dst_info)
+{
+ struct xsc_flow_ipat_del {
+ struct xsc_epat_key key;
+ } del;
+ struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+ memset(&del, 0, sizeof(del));
+
+ del.key.dst_info = dst_info;
+ return xsc_flow_exec(priv->xdev, &del, sizeof(del),
+ XSC_FLOW_TBL_EPAT, XSC_IOCTL_OP_DEL);
+}
+
new file mode 100644
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 Yunsilicon Technology Co., Ltd.
+ */
+
+#ifndef _XSC_FLOW_H_
+#define _XSC_FLOW_H_
+
+#include <rte_byteorder.h>
+
+#include "xsc_dev.h"
+#include "xsc_utils.h"
+
+/* xsc flow */
+struct xsc_ipat_key {
+ uint16_t logical_in_port:11;
+} __rte_packed;
+
+struct xsc_ipat_action {
+ uint64_t rsv0:64;
+ uint16_t rsv1:9;
+ uint16_t dst_info:11;
+ uint64_t rsv2:34;
+ uint8_t vld:1;
+} __rte_packed;
+
+struct xsc_epat_key {
+ uint16_t dst_info:11;
+} __rte_packed;
+
+struct xsc_epat_action {
+ uint8_t rsv0[14];
+ uint8_t rsv1:4;
+ uint8_t dst_port:4;
+ uint8_t rss_hash_func:2;
+ uint8_t rss_hash_template:5;
+ uint8_t rss_en:1;
+ uint8_t qp_num:8;
+ uint16_t rx_qp_id_ofst:12;
+ uint16_t rsv3:4;
+ uint8_t rsv4:7;
+ uint8_t vld:1;
+} __rte_packed;
+
+struct xsc_pct_v4_key {
+ uint16_t rsv0[20];
+ uint16_t rsv1:13;
+ uint16_t logical_in_port:11;
+ uint8_t rsv2:8;
+} __rte_packed;
+
+struct xsc_pct_action {
+ uint32_t rsv0:29;
+ uint16_t dst_info:11;
+ uint8_t rsv1:3;
+} __rte_packed;
+
+int xsc_create_pct(struct rte_eth_dev *dev, uint16_t logical_in_port,
+ uint16_t dst_info, uint32_t priority);
+int xsc_destroy_pct(struct rte_eth_dev *dev, uint16_t logical_in_port, uint32_t priority);
+int xsc_create_ipat(struct rte_eth_dev *dev, uint16_t logic_in_port, uint16_t dst_info);
+int xsc_destroy_ipat(struct rte_eth_dev *dev, uint16_t logic_in_port);
+int xsc_create_epat(struct rte_eth_dev *dev, uint16_t dst_info, uint8_t dst_port,
+ uint16_t qpn_ofst, uint8_t qp_num);
+int xsc_destroy_epat(struct rte_eth_dev *dev, uint16_t dst_info);
+
+#endif
+