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

Signed-off-by: Jingjing Wu <jingjing.wu at 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

Reply via email to