From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <wujingji@shecgisg004.sh.intel.com>
Received: from mga11.intel.com (mga11.intel.com [192.55.52.93])
 by dpdk.org (Postfix) with ESMTP id 3641C7F10
 for <dev@dpdk.org>; Thu, 30 Oct 2014 08:18:52 +0100 (CET)
Received: from fmsmga001.fm.intel.com ([10.253.24.23])
 by fmsmga102.fm.intel.com with ESMTP; 30 Oct 2014 00:27:46 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.07,284,1413270000"; d="scan'208";a="613926599"
Received: from shvmail01.sh.intel.com ([10.239.29.42])
 by fmsmga001.fm.intel.com with ESMTP; 30 Oct 2014 00:27:45 -0700
Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com
 [10.239.29.89])
 by shvmail01.sh.intel.com with ESMTP id s9U7Rh4Q008374;
 Thu, 30 Oct 2014 15:27:43 +0800
Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1])
 by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id
 s9U7RfZq008009; Thu, 30 Oct 2014 15:27:43 +0800
Received: (from wujingji@localhost)
 by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s9U7RfwP008005;
 Thu, 30 Oct 2014 15:27:41 +0800
From: Jingjing Wu <jingjing.wu@intel.com>
To: dev@dpdk.org
Date: Thu, 30 Oct 2014 15:26:45 +0800
Message-Id: <1414654006-7472-21-git-send-email-jingjing.wu@intel.com>
X-Mailer: git-send-email 1.7.4.1
In-Reply-To: <1414654006-7472-1-git-send-email-jingjing.wu@intel.com>
References: <1413939687-11177-1-git-send-email-jingjing.wu@intel.com>
 <1414654006-7472-1-git-send-email-jingjing.wu@intel.com>
Subject: [dpdk-dev] [PATCH v5 20/21] i40e: implement operations to configure
	flexible masks
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Thu, 30 Oct 2014 07:18:52 -0000

Implement operation to flexible masks for each flow type in i40e pmd driver

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_i40e/i40e_fdir.c | 124 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 123 insertions(+), 1 deletion(-)

diff --git a/lib/librte_pmd_i40e/i40e_fdir.c b/lib/librte_pmd_i40e/i40e_fdir.c
index e15d94e..981b6eb 100644
--- a/lib/librte_pmd_i40e/i40e_fdir.c
+++ b/lib/librte_pmd_i40e/i40e_fdir.c
@@ -85,6 +85,8 @@
 static int i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq);
 static int i40e_set_flx_pld_cfg(struct i40e_pf *pf,
 			 struct rte_eth_flex_payload_cfg *cfg);
+static int i40e_set_fdir_flx_mask(struct i40e_pf *pf,
+			struct rte_eth_fdir_flex_masks *flex_masks);
 static int i40e_fdir_construct_pkt(struct i40e_pf *pf,
 				     struct rte_eth_fdir_input *fdir_input,
 				     unsigned char *raw_pkt);
@@ -420,6 +422,123 @@ i40e_set_flx_pld_cfg(struct i40e_pf *pf,
 	return 0;
 }
 
+static inline void
+i40e_set_flex_mask_on_pctype(
+		struct i40e_hw *hw,
+		enum i40e_filter_pctype pctype,
+		struct rte_eth_fdir_flex_masks *flex_masks)
+{
+	uint32_t flxinset, mask;
+	int i;
+
+	flxinset = (flex_masks->words_mask <<
+		I40E_PRTQF_FD_FLXINSET_INSET_SHIFT) &
+		I40E_PRTQF_FD_FLXINSET_INSET_MASK;
+	I40E_WRITE_REG(hw, I40E_PRTQF_FD_FLXINSET(pctype), flxinset);
+
+	for (i = 0; i < flex_masks->nb_field; i++) {
+		mask = (flex_masks->field[i].bitmask <<
+			I40E_PRTQF_FD_MSK_MASK_SHIFT) &
+			I40E_PRTQF_FD_MSK_MASK_MASK;
+		mask |= ((flex_masks->field[i].offset +
+			I40E_FLX_OFFSET_IN_FIELD_VECTOR) <<
+			I40E_PRTQF_FD_MSK_OFFSET_SHIFT) &
+			I40E_PRTQF_FD_MSK_OFFSET_MASK;
+		I40E_WRITE_REG(hw, I40E_PRTQF_FD_MSK(pctype, i), mask);
+	}
+}
+
+/*
+ * i40e_set_fdir_flx_mask - configure the mask on flexible payload
+ * @pf: board private structure
+ * @flex_masks: mask for flexible payload
+ */
+static int
+i40e_set_fdir_flx_mask(struct i40e_pf *pf,
+		struct rte_eth_fdir_flex_masks *flex_masks)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	struct rte_eth_fdir_info fdir;
+	int ret = 0;
+
+	if (flex_masks == NULL)
+		return -EINVAL;
+
+	if (flex_masks->nb_field > 2) {
+		PMD_DRV_LOG(ERR, "bit masks cannot support more than 2 words.");
+		return -EINVAL;
+	}
+	/*
+	 * flexible payload masks need to be configured before
+	 * flow director filters are added
+	 * If filters exist, flush them.
+	 */
+	memset(&fdir, 0, sizeof(fdir));
+	i40e_fdir_info_get(pf, &fdir);
+	if (fdir.best_cnt + fdir.guarant_cnt > 0) {
+		ret = i40e_fdir_flush(pf);
+		if (ret) {
+			PMD_DRV_LOG(ERR, "failed to flush fdir table.");
+			return ret;
+		}
+	}
+
+	switch (flex_masks->flow_type) {
+	case RTE_ETH_FLOW_TYPE_UDPV4:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_TCPV4:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_SCTPV4:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_IPV4_OTHER:
+		/* set mask for both NONF_IPV4 and FRAG_IPV4 PCTYPE*/
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
+			flex_masks);
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_FRAG_IPV4,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_UDPV6:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_TCPV6:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
+			flex_masks);
+	case RTE_ETH_FLOW_TYPE_SCTPV6:
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
+			flex_masks);
+		break;
+	case RTE_ETH_FLOW_TYPE_IPV6_OTHER:
+		/* set mask for both NONF_IPV6 and FRAG_IPV6 PCTYPE*/
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
+			flex_masks);
+		i40e_set_flex_mask_on_pctype(hw,
+			I40E_FILTER_PCTYPE_FRAG_IPV6,
+			flex_masks);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid flow_type input.");
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
 /*
  * i40e_fdir_construct_pkt - construct packet based on fields in input
  * @pf: board private structure
@@ -1081,8 +1200,11 @@ i40e_fdir_ctrl_func(struct i40e_pf *pf, enum rte_filter_op filter_op, void *arg)
 		if (fdir_cfg->cmd == RTE_ETH_FDIR_CFG_FLX)
 			ret = i40e_set_flx_pld_cfg(pf,
 				(struct rte_eth_flex_payload_cfg *)fdir_cfg->cfg);
+		else if (fdir_cfg->cmd == RTE_ETH_FDIR_CFG_FLX_MASK)
+			ret = i40e_set_fdir_flx_mask(pf,
+				(struct rte_eth_fdir_flex_masks *)fdir_cfg->cfg);
 		else {
-			PMD_DRV_LOG(WARNING, "unsupported configuration command %u.",
+			PMD_DRV_LOG(ERR, "unsupported configuration command %u.",
 				    fdir_cfg->cmd);
 			return -EINVAL;
 		}
-- 
1.8.1.4