Currently, we initialize the rule mask to all 1 and mask L4 protocol if port mask is 0. However, this causes some hardware programming issues.
1. raw IPv4 rule incorrectly sets the L4P bit to 0 because it doesn't change port mask. 2. on 82599, SCTP rule incorrectly programe the TCP/UDP/SCTP mask register to 0 because it doesn't change the mask either. 3. SCTP rule on 82599 incorrectly configure the L4P bit to 1 if rule mask is initialized to 0. This patch fixes these issues by changing mask default to 0 and using the flow type as the L4P setting condition. Fixes: 11777435c727 ("net/ixgbe: parse flow director filter") Cc: sta...@dpdk.org Signed-off-by: Yuan Wang <yuanx.w...@intel.com> --- drivers/net/intel/ixgbe/ixgbe_ethdev.c | 1 + drivers/net/intel/ixgbe/ixgbe_ethdev.h | 1 + drivers/net/intel/ixgbe/ixgbe_fdir.c | 3 ++- drivers/net/intel/ixgbe/ixgbe_flow.c | 9 ++++----- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c index 4f0343245e..88c3cb2534 100644 --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c @@ -1470,6 +1470,7 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev) return -ENOMEM; } fdir_info->mask_added = FALSE; + fdir_info->flow_type = 0; return 0; } diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.h b/drivers/net/intel/ixgbe/ixgbe_ethdev.h index 86da9fc89b..13b77cec58 100644 --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.h +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.h @@ -212,6 +212,7 @@ struct ixgbe_hw_fdir_info { struct ixgbe_fdir_filter **hash_map; struct rte_hash *hash_handle; /* cuckoo hash handler */ bool mask_added; /* If already got mask from consistent filter */ + enum ixgbe_atr_flow_type flow_type; }; struct ixgbe_rte_flow_rss_conf { diff --git a/drivers/net/intel/ixgbe/ixgbe_fdir.c b/drivers/net/intel/ixgbe/ixgbe_fdir.c index b6351bc2cf..a686bd4ca5 100644 --- a/drivers/net/intel/ixgbe/ixgbe_fdir.c +++ b/drivers/net/intel/ixgbe/ixgbe_fdir.c @@ -273,7 +273,7 @@ fdir_set_input_mask_82599(struct rte_eth_dev *dev) * a VLAN of 0 is unspecified, so mask that out as well. L4type * cannot be masked out in this implementation. */ - if (info->mask.dst_port_mask == 0 && info->mask.src_port_mask == 0) + if ((info->flow_type & IXGBE_ATR_L4TYPE_MASK) == 0) /* use the L4 protocol mask for raw IPv4/IPv6 traffic */ fdirm |= IXGBE_FDIRM_L4P; @@ -1271,6 +1271,7 @@ ixgbe_fdir_flush(struct rte_eth_dev *dev) info->f_remove = 0; info->add = 0; info->remove = 0; + info->flow_type = 0; return ret; } diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c b/drivers/net/intel/ixgbe/ixgbe_flow.c index 6278646720..c0374be977 100644 --- a/drivers/net/intel/ixgbe/ixgbe_flow.c +++ b/drivers/net/intel/ixgbe/ixgbe_flow.c @@ -1641,11 +1641,6 @@ 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; - rule->mask.dst_port_mask = 0; - rule->mask.src_port_mask = 0; /** * The first not void item should be @@ -2759,6 +2754,8 @@ ixgbe_parse_fdir_filter(struct rte_eth_dev *dev, { int ret; struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ixgbe_hw_fdir_info *fdir_info = + IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private); struct rte_eth_fdir_conf *fdir_conf = IXGBE_DEV_FDIR_CONF(dev); fdir_conf->drop_queue = IXGBE_FDIR_DROP_QUEUE; @@ -2804,6 +2801,8 @@ ixgbe_parse_fdir_filter(struct rte_eth_dev *dev, if (rule->queue >= dev->data->nb_rx_queues) return -ENOTSUP; + fdir_info->flow_type = rule->ixgbe_fdir.formatted.flow_type; + return ret; } -- 2.24.0