net/ixgbe: parse flow director filter
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.h
index f159124..b3f3980 100644 (file)
@@ -38,6 +38,7 @@
 #include "base/ixgbe_dcb_82598.h"
 #include "ixgbe_bypass.h"
 #include <rte_time.h>
+#include <rte_hash.h>
 
 /* need update link, bit flag */
 #define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
 
 #define IXGBE_MACSEC_PNTHRSH            0xFFFFFE00
 
+#define IXGBE_MAX_FDIR_FILTER_NUM       (1024 * 32)
+#define IXGBE_MAX_L2_TN_FILTER_NUM      128
+
 /*
  * Information about the fdir mode.
  */
-
 struct ixgbe_hw_fdir_mask {
        uint16_t vlan_tci_mask;
        uint32_t src_ipv4_mask;
@@ -153,6 +156,28 @@ struct ixgbe_hw_fdir_mask {
        uint8_t  tunnel_type_mask;
 };
 
+struct ixgbe_fdir_filter {
+       TAILQ_ENTRY(ixgbe_fdir_filter) entries;
+       union ixgbe_atr_input ixgbe_fdir; /* key of fdir filter*/
+       uint32_t fdirflags; /* drop or forward */
+       uint32_t fdirhash; /* hash value for fdir */
+       uint8_t queue; /* assigned rx queue */
+};
+
+/* list of fdir filters */
+TAILQ_HEAD(ixgbe_fdir_filter_list, ixgbe_fdir_filter);
+
+struct ixgbe_fdir_rule {
+       struct ixgbe_hw_fdir_mask mask;
+       union ixgbe_atr_input ixgbe_fdir; /* key of fdir filter*/
+       bool b_spec; /* If TRUE, ixgbe_fdir, fdirflags, queue have meaning. */
+       bool b_mask; /* If TRUE, mask has meaning. */
+       enum rte_fdir_mode mode; /* IP, MAC VLAN, Tunnel */
+       uint32_t fdirflags; /* drop or forward */
+       uint32_t soft_id; /* an unique value for this rule */
+       uint8_t queue; /* assigned rx queue */
+};
+
 struct ixgbe_hw_fdir_info {
        struct ixgbe_hw_fdir_mask mask;
        uint8_t     flex_bytes_offset;
@@ -164,6 +189,11 @@ struct ixgbe_hw_fdir_info {
        uint64_t    remove;
        uint64_t    f_add;
        uint64_t    f_remove;
+       struct ixgbe_fdir_filter_list fdir_list; /* filter list*/
+       /* store the pointers of the filters, index is the hash value. */
+       struct ixgbe_fdir_filter **hash_map;
+       struct rte_hash *hash_handle; /* cuckoo hash handler */
+       bool mask_added; /* If already got mask from consistent filter */
 };
 
 /* structure for interrupt relative data */
@@ -257,13 +287,24 @@ struct ixgbe_5tuple_filter {
        (RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, (sizeof(uint32_t) * NBBY)) / \
         (sizeof(uint32_t) * NBBY))
 
+struct ixgbe_ethertype_filter {
+       uint16_t ethertype;
+       uint32_t etqf;
+       uint32_t etqs;
+       /**
+        * If this filter is added by configuration,
+        * it should not be removed.
+        */
+       bool     conf;
+};
+
 /*
  * Structure to store filters' info.
  */
 struct ixgbe_filter_info {
        uint8_t ethertype_mask;  /* Bit mask for every used ethertype filter */
        /* store used ethertype filters*/
-       uint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
+       struct ixgbe_ethertype_filter ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
        /* Bit mask for every used 5tuple filter */
        uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
        struct ixgbe_5tuple_filter_list fivetuple_list;
@@ -271,6 +312,28 @@ struct ixgbe_filter_info {
        uint32_t syn_info;
 };
 
+struct ixgbe_l2_tn_key {
+       enum rte_eth_tunnel_type          l2_tn_type;
+       uint32_t                          tn_id;
+};
+
+struct ixgbe_l2_tn_filter {
+       TAILQ_ENTRY(ixgbe_l2_tn_filter)    entries;
+       struct ixgbe_l2_tn_key             key;
+       uint32_t                           pool;
+};
+
+TAILQ_HEAD(ixgbe_l2_tn_filter_list, ixgbe_l2_tn_filter);
+
+struct ixgbe_l2_tn_info {
+       struct ixgbe_l2_tn_filter_list      l2_tn_list;
+       struct ixgbe_l2_tn_filter         **hash_map;
+       struct rte_hash                    *hash_handle;
+       bool e_tag_en; /* e-tag enabled */
+       bool e_tag_fwd_en; /* e-tag based forwarding enabled */
+       bool e_tag_ether_type; /* ether type for e-tag */
+};
+
 /*
  * Statistics counters collected by the MACsec
  */
@@ -323,6 +386,7 @@ struct ixgbe_adapter {
        struct ixgbe_bypass_info    bps;
 #endif /* RTE_NIC_BYPASS */
        struct ixgbe_filter_info    filter;
+       struct ixgbe_l2_tn_info     l2_tn;
 
        bool rx_bulk_alloc_allowed;
        bool rx_vec_allowed;
@@ -373,6 +437,9 @@ struct ixgbe_adapter {
 #define IXGBE_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
        (&((struct ixgbe_adapter *)adapter)->filter)
 
+#define IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(adapter) \
+       (&((struct ixgbe_adapter *)adapter)->l2_tn)
+
 /*
  * RX/TX function prototypes
  */
@@ -465,6 +532,10 @@ bool ixgbe_rss_update_sp(enum ixgbe_mac_type mac_type);
  * Flow director function prototypes
  */
 int ixgbe_fdir_configure(struct rte_eth_dev *dev);
+int ixgbe_fdir_set_input_mask(struct rte_eth_dev *dev);
+int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
+                             struct ixgbe_fdir_rule *rule,
+                             bool del, bool update);
 
 void ixgbe_configure_dcb(struct rte_eth_dev *dev);
 
@@ -491,8 +562,69 @@ uint32_t ixgbe_convert_vm_rx_mask_to_val(uint16_t rx_mask, uint32_t orig_val);
 
 int ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev,
                        enum rte_filter_op filter_op, void *arg);
+void ixgbe_fdir_filter_restore(struct rte_eth_dev *dev);
+int ixgbe_clear_all_fdir_filter(struct rte_eth_dev *dev);
+
+extern const struct rte_flow_ops ixgbe_flow_ops;
+
+void ixgbe_clear_all_ethertype_filter(struct rte_eth_dev *dev);
+void ixgbe_clear_all_ntuple_filter(struct rte_eth_dev *dev);
+void ixgbe_clear_syn_filter(struct rte_eth_dev *dev);
+int ixgbe_clear_all_l2_tn_filter(struct rte_eth_dev *dev);
 
 int ixgbe_disable_sec_tx_path_generic(struct ixgbe_hw *hw);
 
 int ixgbe_enable_sec_tx_path_generic(struct ixgbe_hw *hw);
+
+static inline int
+ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,
+                             uint16_t ethertype)
+{
+       int i;
+
+       for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+               if (filter_info->ethertype_filters[i].ethertype == ethertype &&
+                   (filter_info->ethertype_mask & (1 << i)))
+                       return i;
+       }
+       return -1;
+}
+
+static inline int
+ixgbe_ethertype_filter_insert(struct ixgbe_filter_info *filter_info,
+                             struct ixgbe_ethertype_filter *ethertype_filter)
+{
+       int i;
+
+       for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+               if (!(filter_info->ethertype_mask & (1 << i))) {
+                       filter_info->ethertype_mask |= 1 << i;
+                       filter_info->ethertype_filters[i].ethertype =
+                               ethertype_filter->ethertype;
+                       filter_info->ethertype_filters[i].etqf =
+                               ethertype_filter->etqf;
+                       filter_info->ethertype_filters[i].etqs =
+                               ethertype_filter->etqs;
+                       filter_info->ethertype_filters[i].conf =
+                               ethertype_filter->conf;
+                       return i;
+               }
+       }
+       return -1;
+}
+
+static inline int
+ixgbe_ethertype_filter_remove(struct ixgbe_filter_info *filter_info,
+                             uint8_t idx)
+{
+       if (idx >= IXGBE_MAX_ETQF_FILTERS)
+               return -1;
+       filter_info->ethertype_mask &= ~(1 << idx);
+       filter_info->ethertype_filters[idx].ethertype = 0;
+       filter_info->ethertype_filters[idx].etqf = 0;
+       filter_info->ethertype_filters[idx].etqs = 0;
+       filter_info->ethertype_filters[idx].etqs = FALSE;
+       return idx;
+}
+
 #endif /* _IXGBE_ETHDEV_H_ */