Add yuan.p...@intel.com into mail loop

> -----Original Message-----
> From: Zhao1, Wei
> Sent: Monday, December 17, 2018 1:53 PM
> To: dev@dpdk.org
> Cc: adrien.mazarg...@6wind.com; sta...@dpdk.org; Lu, Wenzhuo
> <wenzhuo...@intel.com>; Zhang, Qi Z <qi.z.zh...@intel.com>; Zhao1, Wei
> <wei.zh...@intel.com>
> Subject: [PATCH] net/ixgbe: enable x550 flexible byte filter
> 
> There is need for users to use flexible byte filter on x550.
> This patch enable it.
> 
> Fixes: 82fb702077f6 ("ixgbe: support new flow director modes for X550")
> Fixes: 11777435c727 ("net/ixgbe: parse flow director filter")
> 
> Signed-off-by: Wei Zhao <wei.zh...@intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_fdir.c |   9 +-
>  drivers/net/ixgbe/ixgbe_flow.c | 274 ++++++++++++++++++++++++++++--
> -----------
>  2 files changed, 195 insertions(+), 88 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_fdir.c b/drivers/net/ixgbe/ixgbe_fdir.c
> index e559f0f..deb9a21 100644
> --- a/drivers/net/ixgbe/ixgbe_fdir.c
> +++ b/drivers/net/ixgbe/ixgbe_fdir.c
> @@ -307,6 +307,8 @@ fdir_set_input_mask_82599(struct rte_eth_dev *dev)
>       /* flex byte mask */
>       if (info->mask.flex_bytes_mask == 0)
>               fdirm |= IXGBE_FDIRM_FLEX;
> +     if (info->mask.src_ipv4_mask == 0 && info->mask.dst_ipv4_mask ==
> 0)
> +             fdirm |= IXGBE_FDIRM_L3P;
> 
>       IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
> 
> @@ -356,8 +358,7 @@ fdir_set_input_mask_x550(struct rte_eth_dev *dev)
>       /* mask VM pool and DIPv6 since there are currently not supported
>        * mask FLEX byte, it will be set in flex_conf
>        */
> -     uint32_t fdirm = IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6 |
> -                      IXGBE_FDIRM_FLEX;
> +     uint32_t fdirm = IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6;
>       uint32_t fdiripv6m;
>       enum rte_fdir_mode mode = dev->data->dev_conf.fdir_conf.mode;
>       uint16_t mac_mask;
> @@ -385,6 +386,10 @@ fdir_set_input_mask_x550(struct rte_eth_dev *dev)
>               return -EINVAL;
>       }
> 
> +     /* flex byte mask */
> +     if (info->mask.flex_bytes_mask == 0)
> +             fdirm |= IXGBE_FDIRM_FLEX;
> +
>       IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
> 
>       fdiripv6m = ((u32)0xFFFFU << IXGBE_FDIRIP6M_DIPM_SHIFT); diff --
> git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c index
> f0fafeb..dc210c5 100644
> --- a/drivers/net/ixgbe/ixgbe_flow.c
> +++ b/drivers/net/ixgbe/ixgbe_flow.c
> @@ -1622,9 +1622,9 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev
> *dev,
>       const struct rte_flow_item_raw *raw_mask;
>       const struct rte_flow_item_raw *raw_spec;
>       uint8_t j;
> -
>       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> 
> +
>       if (!pattern) {
>               rte_flow_error_set(error, EINVAL,
>                       RTE_FLOW_ERROR_TYPE_ITEM_NUM,
> @@ -1651,9 +1651,7 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev
> *dev,
>        * value. So, we need not do anything for the not provided fields
> later.
>        */
>       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -     memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
> -     rule->mask.vlan_tci_mask = 0;
> -     rule->mask.flex_bytes_mask = 0;
> +     memset(&rule->mask, 0, sizeof(struct ixgbe_hw_fdir_mask));
> 
>       /**
>        * The first not void item should be
> @@ -1665,7 +1663,8 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev
> *dev,
>           item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
>           item->type != RTE_FLOW_ITEM_TYPE_TCP &&
>           item->type != RTE_FLOW_ITEM_TYPE_UDP &&
> -         item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
> +         item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
> +         item->type != RTE_FLOW_ITEM_TYPE_RAW) {
>               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
>               rte_flow_error_set(error, EINVAL,
>                       RTE_FLOW_ERROR_TYPE_ITEM,
> @@ -2201,6 +2200,7 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev
> *dev,
>               }
> 
>               raw_mask = item->mask;
> +             rule->b_mask = TRUE;
> 
>               /* check mask */
>               if (raw_mask->relative != 0x1 ||
> @@ -2217,6 +2217,7 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev
> *dev,
>               }
> 
>               raw_spec = item->spec;
> +             rule->b_spec = TRUE;
> 
>               /* check spec */
>               if (raw_spec->relative != 0 ||
> @@ -2323,6 +2324,8 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>       const struct rte_flow_item_eth *eth_mask;
>       const struct rte_flow_item_vlan *vlan_spec;
>       const struct rte_flow_item_vlan *vlan_mask;
> +     const struct rte_flow_item_raw *raw_mask;
> +     const struct rte_flow_item_raw *raw_spec;
>       uint32_t j;
> 
>       if (!pattern) {
> @@ -2351,8 +2354,7 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>        * value. So, we need not do anything for the not provided fields
> later.
>        */
>       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -     memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
> -     rule->mask.vlan_tci_mask = 0;
> +     memset(&rule->mask, 0, sizeof(struct ixgbe_hw_fdir_mask));
> 
>       /**
>        * The first not void item should be
> @@ -2364,7 +2366,8 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>           item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
>           item->type != RTE_FLOW_ITEM_TYPE_UDP &&
>           item->type != RTE_FLOW_ITEM_TYPE_VXLAN &&
> -         item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
> +         item->type != RTE_FLOW_ITEM_TYPE_NVGRE &&
> +         item->type != RTE_FLOW_ITEM_TYPE_RAW) {
>               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
>               rte_flow_error_set(error, EINVAL,
>                       RTE_FLOW_ERROR_TYPE_ITEM,
> @@ -2520,6 +2523,18 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>                               &rule->ixgbe_fdir.formatted.tni_vni),
>                               vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
>               }
> +             /* check if the next not void item is MAC VLAN RAW or
> END*/
> +             item = next_no_void_pattern(pattern, item);
> +             if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_VLAN &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_RAW &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_END){
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
>       }
> 
>       /* Get the NVGRE info */
> @@ -2616,16 +2631,19 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>                       rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
>                       nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
>               }
> -     }
> 
> -     /* check if the next not void item is MAC */
> -     item = next_no_void_pattern(pattern, item);
> -     if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
> -             memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -             rte_flow_error_set(error, EINVAL,
> -                     RTE_FLOW_ERROR_TYPE_ITEM,
> -                     item, "Not supported by fdir filter");
> -             return -rte_errno;
> +             /* check if the next not void item is MAC VLAN RAW or
> END*/
> +             item = next_no_void_pattern(pattern, item);
> +             if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_VLAN &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_RAW &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_END){
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
>       }
> 
>       /**
> @@ -2633,92 +2651,91 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>        * others should be masked.
>        */
> 
> -     if (!item->mask) {
> -             memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -             rte_flow_error_set(error, EINVAL,
> -                     RTE_FLOW_ERROR_TYPE_ITEM,
> -                     item, "Not supported by fdir filter");
> -             return -rte_errno;
> -     }
> -     /*Not supported last point for range*/
> -     if (item->last) {
> -             rte_flow_error_set(error, EINVAL,
> -                     RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> -                     item, "Not supported last point for range");
> -             return -rte_errno;
> -     }
> -     rule->b_mask = TRUE;
> -     eth_mask = item->mask;
> -
> -     /* Ether type should be masked. */
> -     if (eth_mask->type) {
> -             memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -             rte_flow_error_set(error, EINVAL,
> -                     RTE_FLOW_ERROR_TYPE_ITEM,
> -                     item, "Not supported by fdir filter");
> -             return -rte_errno;
> -     }
> -
> -     /* src MAC address should be masked. */
> -     for (j = 0; j < ETHER_ADDR_LEN; j++) {
> -             if (eth_mask->src.addr_bytes[j]) {
> -                     memset(rule, 0,
> -                            sizeof(struct ixgbe_fdir_rule));
> +     if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
> +             if (!item->mask) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
>                       rte_flow_error_set(error, EINVAL,
>                               RTE_FLOW_ERROR_TYPE_ITEM,
>                               item, "Not supported by fdir filter");
>                       return -rte_errno;
>               }
> -     }
> -     rule->mask.mac_addr_byte_mask = 0;
> -     for (j = 0; j < ETHER_ADDR_LEN; j++) {
> -             /* It's a per byte mask. */
> -             if (eth_mask->dst.addr_bytes[j] == 0xFF) {
> -                     rule->mask.mac_addr_byte_mask |= 0x1 << j;
> -             } else if (eth_mask->dst.addr_bytes[j]) {
> -                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +             /*Not supported last point for range*/
> +             if (item->last) {
>                       rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +                             item, "Not supported last point for range");
> +                     return -rte_errno;
> +             }
> +             rule->b_mask = TRUE;
> +             eth_mask = item->mask;
> +
> +             /* Ether type should be masked. */
> +             if (eth_mask->type) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                             rte_flow_error_set(error, EINVAL,
>                               RTE_FLOW_ERROR_TYPE_ITEM,
>                               item, "Not supported by fdir filter");
>                       return -rte_errno;
>               }
> -     }
> 
> -     /* When no vlan, considered as full mask. */
> -     rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
> -
> -     if (item->spec) {
> -             rule->b_spec = TRUE;
> -             eth_spec = item->spec;
> -
> -             /* Get the dst MAC. */
> +             /* src MAC address should be masked. */
>               for (j = 0; j < ETHER_ADDR_LEN; j++) {
> -                     rule->ixgbe_fdir.formatted.inner_mac[j] =
> -                             eth_spec->dst.addr_bytes[j];
> +                     if (eth_mask->src.addr_bytes[j]) {
> +                             memset(rule, 0,
> +                            sizeof(struct ixgbe_fdir_rule));
> +                             rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                             return -rte_errno;
> +                     }
> +             }
> +             for (j = 0; j < ETHER_ADDR_LEN; j++) {
> +                     /* It's a per byte mask. */
> +                     if (eth_mask->dst.addr_bytes[j] == 0xFF) {
> +                             rule->mask.mac_addr_byte_mask |= 0x1 << j;
> +                     } else if (eth_mask->dst.addr_bytes[j]) {
> +                             memset(rule, 0, sizeof(struct
> ixgbe_fdir_rule));
> +                             rte_flow_error_set(error, EINVAL,
> +                                     RTE_FLOW_ERROR_TYPE_ITEM,
> +                                     item, "Not supported by fdir filter");
> +                             return -rte_errno;
> +                     }
>               }
> -     }
> 
> -     /**
> -      * Check if the next not void item is vlan or ipv4.
> -      * IPv6 is not supported.
> -      */
> -     item = next_no_void_pattern(pattern, item);
> -     if ((item->type != RTE_FLOW_ITEM_TYPE_VLAN) &&
> -             (item->type != RTE_FLOW_ITEM_TYPE_IPV4)) {
> -             memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> -             rte_flow_error_set(error, EINVAL,
> -                     RTE_FLOW_ERROR_TYPE_ITEM,
> -                     item, "Not supported by fdir filter");
> -             return -rte_errno;
> -     }
> -     /*Not supported last point for range*/
> -     if (item->last) {
> -             rte_flow_error_set(error, EINVAL,
> +             if (item->spec) {
> +                     rule->b_spec = TRUE;
> +                     eth_spec = item->spec;
> +
> +                     /* Get the dst MAC. */
> +                     for (j = 0; j < ETHER_ADDR_LEN; j++) {
> +                             rule->ixgbe_fdir.formatted.inner_mac[j] =
> +                                     eth_spec->dst.addr_bytes[j];
> +                     }
> +             }
> +             /**
> +              * Check if the next not void item is vlan or ipv4.
> +              * IPv6 is not supported.
> +              */
> +             item = next_no_void_pattern(pattern, item);
> +             if (item->type != RTE_FLOW_ITEM_TYPE_VLAN &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_RAW &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_END) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +                     /*Not supported last point for range*/
> +             if (item->last) {
> +                     rte_flow_error_set(error, EINVAL,
>                       RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>                       item, "Not supported last point for range");
> -             return -rte_errno;
> +                     return -rte_errno;
> +             }
>       }
> 
> +
>       if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
>               if (!(item->spec && item->mask)) {
>                       memset(rule, 0, sizeof(struct ixgbe_fdir_rule)); @@ -
> 2736,10 +2753,90 @@ ixgbe_parse_fdir_filter_tunnel(const struct
> rte_flow_attr *attr,
>               rule->mask.vlan_tci_mask = vlan_mask->tci;
>               rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
>               /* More than one tags are not supported. */
> +             item = next_no_void_pattern(pattern, item);
> +             if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
> +                     item->type != RTE_FLOW_ITEM_TYPE_END) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +     }
> +
> +     /* Get the flex byte info */
> +     if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
> +             /* Not supported last point for range*/
> +             if (item->last) {
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +                             item, "Not supported last point for range");
> +                     return -rte_errno;
> +             }
> +             /* mask should not be null */
> +             if (!item->mask || !item->spec) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +
> +             raw_mask = item->mask;
> +             rule->b_mask = TRUE;
> 
> +             /* check mask */
> +             if (raw_mask->relative != 0x1 ||
> +                 raw_mask->search != 0x1 ||
> +                 raw_mask->reserved != 0x0 ||
> +                 (uint32_t)raw_mask->offset != 0xffffffff ||
> +                 raw_mask->limit != 0xffff ||
> +                 raw_mask->length != 0xffff) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +
> +             raw_spec = item->spec;
> +             rule->b_spec = TRUE;
> +
> +             /* check spec */
> +             if (raw_spec->relative != 0 ||
> +                 raw_spec->search != 0 ||
> +                 raw_spec->reserved != 0 ||
> +                 raw_spec->offset > IXGBE_MAX_FLX_SOURCE_OFF ||
> +                 raw_spec->offset % 2 ||
> +                 raw_spec->limit != 0 ||
> +                 raw_spec->length != 2 ||
> +                 /* pattern can't be 0xffff */
> +                 (raw_spec->pattern[0] == 0xff &&
> +                  raw_spec->pattern[1] == 0xff)) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +
> +             /* check pattern mask */
> +             if (raw_mask->pattern[0] != 0xff ||
> +                 raw_mask->pattern[1] != 0xff) {
> +                     memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
> +                     rte_flow_error_set(error, EINVAL,
> +                             RTE_FLOW_ERROR_TYPE_ITEM,
> +                             item, "Not supported by fdir filter");
> +                     return -rte_errno;
> +             }
> +
> +             rule->mask.flex_bytes_mask = 0xffff;
> +             rule->ixgbe_fdir.formatted.flex_bytes =
> +                     (((uint16_t)raw_spec->pattern[1]) << 8) |
> +                     raw_spec->pattern[0];
> +             rule->flex_bytes_offset = raw_spec->offset;
>               /* check if the next not void item is END */
>               item = next_no_void_pattern(pattern, item);
> -
>               if (item->type != RTE_FLOW_ITEM_TYPE_END) {
>                       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
>                       rte_flow_error_set(error, EINVAL,
> @@ -2776,12 +2873,17 @@ ixgbe_parse_fdir_filter(struct rte_eth_dev *dev,
>               hw->mac.type != ixgbe_mac_X550EM_a)
>               return -ENOTSUP;
> 
> +     if (fdir_mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
> +             goto tunnel_filter;
> +
>       ret = ixgbe_parse_fdir_filter_normal(dev, attr, pattern,
>                                       actions, rule, error);
> 
>       if (!ret)
>               goto step_next;
> 
> +tunnel_filter:
> +
>       ret = ixgbe_parse_fdir_filter_tunnel(attr, pattern,
>                                       actions, rule, error);
> 
> --
> 2.7.5

Reply via email to