From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 9E92842528;
	Wed,  6 Sep 2023 11:35:33 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 8B462402E8;
	Wed,  6 Sep 2023 11:34:48 +0200 (CEST)
Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.120])
 by mails.dpdk.org (Postfix) with ESMTP id 6C73D40689
 for <dev@dpdk.org>; Wed,  6 Sep 2023 11:34:47 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1693992887; x=1725528887;
 h=from:to:cc:subject:date:message-id:in-reply-to:
 references:mime-version:content-transfer-encoding;
 bh=QlG/7fT5HttIuIo08iAakWJVdJNzppuR/g5t7hNEcN8=;
 b=AaGVarFB0ac9KAhLq0qcj5L2D/KX1cFoNIriTIB59wPPpzZt0CycFKah
 JtwsAPnY4nSikIepUgw73uJt4HlVwoaShplP3xYdqbynyKYQphPb7ILIW
 UZMuGYAYBqR++3Yn9/Z8yp8z0JcX71M7bxIYyWZC+KAfFuebd5y24KCsh
 P0sRFql1H2AqZmMCsJeFG676K/bSEXrGbtJ6Ndwr8km8CQoeDJq7SRl98
 3m0zv/ws3kdtXfE7Nf9oahP26Yxbh3M7osUX6LaZDBb1r0l8JeERszll9
 JF9uD1KC8+J7i6R682kj9zNmY8xu/l54QwjmXkzo/9573shWNDzPiIEp9 w==;
X-IronPort-AV: E=McAfee;i="6600,9927,10824"; a="375919409"
X-IronPort-AV: E=Sophos;i="6.02,231,1688454000"; d="scan'208";a="375919409"
Received: from fmsmga001.fm.intel.com ([10.253.24.23])
 by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 06 Sep 2023 02:34:46 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=McAfee;i="6600,9927,10824"; a="884623223"
X-IronPort-AV: E=Sophos;i="6.02,231,1688454000"; d="scan'208";a="884623223"
Received: from dpdk-wenjing-02.sh.intel.com ([10.67.119.75])
 by fmsmga001.fm.intel.com with ESMTP; 06 Sep 2023 02:34:34 -0700
From: Wenjing Qiao <wenjing.qiao@intel.com>
To: yuying.zhang@intel.com, dev@dpdk.org, qi.z.zhang@intel.com,
 jingjing.wu@intel.com, beilei.xing@intel.com
Cc: mingxia.liu@intel.com
Subject: [PATCH v3 8/9] net/cpfl: add flow support for representor
Date: Wed,  6 Sep 2023 09:34:06 +0000
Message-Id: <20230906093407.3635038-9-wenjing.qiao@intel.com>
X-Mailer: git-send-email 2.34.1
In-Reply-To: <20230906093407.3635038-1-wenjing.qiao@intel.com>
References: <20230901113158.1654044-1-yuying.zhang@intel.com>
 <20230906093407.3635038-1-wenjing.qiao@intel.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

From: Yuying Zhang <yuying.zhang@intel.com>

Add flow support for representor, so representor can
create, destroy, validate and flush rules.

Signed-off-by: Yuying Zhang <yuying.zhang@intel.com>
---
 doc/guides/nics/cpfl.rst                | 13 ++++
 doc/guides/rel_notes/release_23_11.rst  |  1 +
 drivers/net/cpfl/cpfl_flow_engine_fxp.c | 90 ++++++++++++++++++++++++-
 drivers/net/cpfl/cpfl_representor.c     | 29 ++++++++
 4 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/cpfl.rst b/doc/guides/nics/cpfl.rst
index 7032dd1a1a..e2fe5430ed 100644
--- a/doc/guides/nics/cpfl.rst
+++ b/doc/guides/nics/cpfl.rst
@@ -196,3 +196,16 @@ low level hardware resources defined in a DDP package file.
    .. code-block:: console
 
    dpdk-testpmd -c 0x3 -n 4 -a 0000:af:00.6,vport=[0],flow_parser="refpkg.json" -- -i
+
+#. Create one flow to forward ETH-IPV4-TCP from I/O port to a local(CPF's) vport::
+
+   .. code-block:: console
+
+   flow create 0 ingress group 1 pattern eth dst is 00:01:00:00:03:14 / ipv4 src is 192.168.0.1 \
+   dst is 192.168.0.2 / tcp / end actions port_representor port_id 0 / end
+
+#. Send the packet, and it should be displayed on PMD::
+
+   .. code-block:: console
+
+   sendp(Ether(dst='00:01:00:00:03:14')/IP(src='192.168.0.1',dst='192.168.0.2')/TCP(),iface="enp24s0f0")
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 688bee4d6d..eded3ecc84 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -58,6 +58,7 @@ New Features
 * **Updated Intel cpfl driver.**
 
   * Added support for port representor.
+  * Added support for rte_flow.
 
 Removed Items
 -------------
diff --git a/drivers/net/cpfl/cpfl_flow_engine_fxp.c b/drivers/net/cpfl/cpfl_flow_engine_fxp.c
index e0c08a77c3..fed18d8349 100644
--- a/drivers/net/cpfl/cpfl_flow_engine_fxp.c
+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c
@@ -73,6 +73,7 @@ cpfl_fxp_create(struct rte_eth_dev *dev,
 	struct cpfl_adapter_ext *ad = itf->adapter;
 	struct cpfl_rule_info_meta *rim = meta;
 	struct cpfl_vport *vport;
+	struct cpfl_repr *repr;
 
 	if (!rim)
 		return ret;
@@ -83,6 +84,10 @@ cpfl_fxp_create(struct rte_eth_dev *dev,
 		 * Even index is tx queue and odd index is rx queue.
 		 */
 		cpq_id = vport->base.devarg_id * 2;
+	} else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
+		repr = (struct cpfl_repr *)itf;
+		cpq_id = ((repr->repr_id.pf_id  + repr->repr_id.vf_id) &
+			  (CPFL_TX_CFGQ_NUM - 1)) * 2;
 	} else {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
 				   "fail to find correct control queue");
@@ -122,6 +127,7 @@ cpfl_fxp_destroy(struct rte_eth_dev *dev,
 	struct cpfl_rule_info_meta *rim;
 	uint32_t i;
 	struct cpfl_vport *vport;
+	struct cpfl_repr *repr;
 
 	rim = flow->rule;
 	if (!rim) {
@@ -135,6 +141,10 @@ cpfl_fxp_destroy(struct rte_eth_dev *dev,
 	if (itf->type == CPFL_ITF_TYPE_VPORT) {
 		vport = (struct cpfl_vport *)itf;
 		cpq_id = vport->base.devarg_id * 2;
+	} else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
+		repr = (struct cpfl_repr *)itf;
+		cpq_id = ((repr->repr_id.pf_id  + repr->repr_id.vf_id) &
+			  (CPFL_TX_CFGQ_NUM - 1)) * 2;
 	} else {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
 				   "fail to find correct control queue");
@@ -257,6 +267,7 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
 	int queue_id = -1;
 	bool fwd_vsi = false;
 	bool fwd_q = false;
+	bool is_vsi;
 	uint32_t i;
 	struct cpfl_rule_info *rinfo = &rim->rules[index];
 	union cpfl_action_set *act_set = (void *)rinfo->act_bytes;
@@ -267,6 +278,7 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
 		action_type = action->type;
 		switch (action_type) {
 		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			if (!fwd_vsi)
 				fwd_vsi = true;
 			else
@@ -285,12 +297,20 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
 				queue_id = CPFL_INVALID_QUEUE_ID;
 			}
 
-			dev_id = cpfl_get_vsi_id(dst_itf);
+			is_vsi = (action_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR ||
+				  dst_itf->type == CPFL_ITF_TYPE_REPRESENTOR);
+			if (is_vsi)
+				dev_id = cpfl_get_vsi_id(dst_itf);
+			else
+				dev_id = cpfl_get_port_id(dst_itf);
 
 			if (dev_id == CPFL_INVALID_HW_ID)
 				goto err;
 
-			*act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);
+			if (is_vsi)
+				*act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);
+			else
+				*act_set = cpfl_act_fwd_port(0, priority, 0, dev_id);
 			act_set++;
 			rinfo->act_byte_len += sizeof(union cpfl_action_set);
 			break;
@@ -414,6 +434,64 @@ cpfl_is_mod_action(const struct rte_flow_action actions[])
 	return false;
 }
 
+static bool
+cpfl_fxp_get_metadata_port(struct cpfl_itf *itf,
+			   const struct rte_flow_action actions[])
+{
+	const struct rte_flow_action *action;
+	enum rte_flow_action_type action_type;
+	const struct rte_flow_action_ethdev *ethdev;
+	struct cpfl_itf *target_itf;
+	bool ret;
+
+	if (itf->type == CPFL_ITF_TYPE_VPORT) {
+		ret = cpfl_metadata_write_port_id(itf);
+		if (!ret) {
+			PMD_DRV_LOG(ERR, "fail to write port id");
+			return false;
+		}
+	}
+
+	ret = cpfl_metadata_write_sourcevsi(itf);
+	if (!ret) {
+		PMD_DRV_LOG(ERR, "fail to write source vsi id");
+		return false;
+	}
+
+	ret = cpfl_metadata_write_vsi(itf);
+	if (!ret) {
+		PMD_DRV_LOG(ERR, "fail to write vsi id");
+		return false;
+	}
+
+	if (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END)
+		return false;
+
+	for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
+		action_type = action->type;
+		switch (action_type) {
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
+		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+			ethdev = (const struct rte_flow_action_ethdev *)action->conf;
+			target_itf = cpfl_get_itf_by_port_id(ethdev->port_id);
+			if (!target_itf) {
+				PMD_DRV_LOG(ERR, "fail to get target_itf by port id");
+				return false;
+			}
+			ret = cpfl_metadata_write_targetvsi(target_itf);
+			if (!ret) {
+				PMD_DRV_LOG(ERR, "fail to write target vsi id");
+				return false;
+			}
+			break;
+		default:
+			continue;
+		}
+	}
+
+	return true;
+}
+
 static int
 cpfl_fxp_parse_pattern_action(struct rte_eth_dev *dev,
 			      const struct rte_flow_attr *attr,
@@ -430,7 +508,13 @@ cpfl_fxp_parse_pattern_action(struct rte_eth_dev *dev,
 	struct cpfl_rule_info_meta *rim;
 	int ret;
 
-	ret = cpfl_flow_parse_items(adapter->flow_parser, pattern, attr, &pr_action);
+	ret = cpfl_fxp_get_metadata_port(itf, actions);
+	if (!ret) {
+		PMD_DRV_LOG(ERR, "Fail to save metadata.");
+		return -EINVAL;
+	}
+
+	ret = cpfl_flow_parse_items(itf, adapter->flow_parser, pattern, attr, &pr_action);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "No Match pattern support.");
 		return -EINVAL;
diff --git a/drivers/net/cpfl/cpfl_representor.c b/drivers/net/cpfl/cpfl_representor.c
index 83069d0830..6e7d3fd0a6 100644
--- a/drivers/net/cpfl/cpfl_representor.c
+++ b/drivers/net/cpfl/cpfl_representor.c
@@ -4,6 +4,8 @@
 
 #include "cpfl_representor.h"
 #include "cpfl_rxtx.h"
+#include "cpfl_flow.h"
+#include "cpfl_rules.h"
 
 static int
 cpfl_repr_whitelist_update(struct cpfl_adapter_ext *adapter,
@@ -325,6 +327,22 @@ cpfl_repr_link_update(struct rte_eth_dev *ethdev,
 	return 0;
 }
 
+static int
+cpfl_dev_repr_flow_ops_get(struct rte_eth_dev *dev,
+			   const struct rte_flow_ops **ops)
+{
+	if (!dev)
+		return -EINVAL;
+
+#ifdef CPFL_FLOW_JSON_SUPPORT
+	*ops = &cpfl_flow_ops;
+#else
+	*ops = NULL;
+	PMD_DRV_LOG(NOTICE, "not support rte_flow, please install json-c library.");
+#endif
+	return 0;
+}
+
 static const struct eth_dev_ops cpfl_repr_dev_ops = {
 	.dev_start		= cpfl_repr_dev_start,
 	.dev_stop		= cpfl_repr_dev_stop,
@@ -336,6 +354,7 @@ static const struct eth_dev_ops cpfl_repr_dev_ops = {
 	.tx_queue_setup		= idpf_repr_tx_queue_setup,
 
 	.link_update		= cpfl_repr_link_update,
+	.flow_ops_get		= cpfl_dev_repr_flow_ops_get,
 };
 
 static int
@@ -344,6 +363,7 @@ cpfl_repr_init(struct rte_eth_dev *eth_dev, void *init_param)
 	struct cpfl_repr *repr = CPFL_DEV_TO_REPR(eth_dev);
 	struct cpfl_repr_param *param = init_param;
 	struct cpfl_adapter_ext *adapter = param->adapter;
+	int ret;
 
 	repr->repr_id = param->repr_id;
 	repr->vport_info = param->vport_info;
@@ -353,6 +373,15 @@ cpfl_repr_init(struct rte_eth_dev *eth_dev, void *init_param)
 	if (repr->vport_info->vport_info.vport_status == CPCHNL2_VPORT_STATUS_ENABLED)
 		repr->func_up = true;
 
+	TAILQ_INIT(&repr->itf.flow_list);
+	memset(repr->itf.dma, 0, sizeof(repr->itf.dma));
+	memset(repr->itf.msg, 0, sizeof(repr->itf.msg));
+	ret = cpfl_alloc_dma_mem_batch(&repr->itf.flow_dma, repr->itf.dma,
+				       sizeof(union cpfl_rule_cfg_pkt_record),
+				       CPFL_FLOW_BATCH_SIZE);
+	if (ret < 0)
+		return ret;
+
 	eth_dev->dev_ops = &cpfl_repr_dev_ops;
 
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
-- 
2.34.1