Add flow director filter init and uninit operations.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_type.h | 29 +++++++++++++
drivers/net/txgbe/txgbe_ethdev.c | 63 +++++++++++++++++++++++++++++
drivers/net/txgbe/txgbe_ethdev.h | 51 +++++++++++++++++++++++
3 files changed, 143 insertions(+)
@@ -67,6 +67,35 @@ enum {
#define TXGBE_ATR_HASH_MASK 0x7fff
+/* Flow Director ATR input struct. */
+struct txgbe_atr_input {
+ /*
+ * Byte layout in order, all values with MSB first:
+ *
+ * vm_pool - 1 byte
+ * flow_type - 1 byte
+ * vlan_id - 2 bytes
+ * src_ip - 16 bytes
+ * inner_mac - 6 bytes
+ * cloud_mode - 2 bytes
+ * tni_vni - 4 bytes
+ * dst_ip - 16 bytes
+ * src_port - 2 bytes
+ * dst_port - 2 bytes
+ * flex_bytes - 2 bytes
+ * bkt_hash - 2 bytes
+ */
+ u8 vm_pool;
+ u8 flow_type;
+ __be16 pkt_type;
+ __be32 dst_ip[4];
+ __be32 src_ip[4];
+ __be16 src_port;
+ __be16 dst_port;
+ __be16 flex_bytes;
+ __be16 bkt_hash;
+};
+
enum txgbe_eeprom_type {
txgbe_eeprom_unknown = 0,
txgbe_eeprom_spi,
@@ -88,6 +88,8 @@ static const struct reg_info *txgbe_regs_others[] = {
txgbe_regs_diagnostic,
NULL};
+static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
+static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
static int txgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
static int txgbe_dev_set_link_up(struct rte_eth_dev *dev);
@@ -690,6 +692,9 @@ eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
/* initialize 5tuple filter list */
TAILQ_INIT(&filter_info->fivetuple_list);
+ /* initialize flow director filter list & hash */
+ txgbe_fdir_filter_init(eth_dev);
+
/* initialize l2 tunnel filter list & hash */
txgbe_l2_tn_filter_init(eth_dev);
@@ -729,6 +734,26 @@ static int txgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
+static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
+ struct txgbe_fdir_filter *fdir_filter;
+
+ if (fdir_info->hash_map)
+ rte_free(fdir_info->hash_map);
+ if (fdir_info->hash_handle)
+ rte_hash_free(fdir_info->hash_handle);
+
+ while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
+ TAILQ_REMOVE(&fdir_info->fdir_list,
+ fdir_filter,
+ entries);
+ rte_free(fdir_filter);
+ }
+
+ return 0;
+}
+
static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
{
struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(eth_dev);
@@ -749,6 +774,41 @@ static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
+static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
+{
+ struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
+ char fdir_hash_name[RTE_HASH_NAMESIZE];
+ struct rte_hash_parameters fdir_hash_params = {
+ .name = fdir_hash_name,
+ .entries = TXGBE_MAX_FDIR_FILTER_NUM,
+ .key_len = sizeof(struct txgbe_atr_input),
+ .hash_func = rte_hash_crc,
+ .hash_func_init_val = 0,
+ .socket_id = rte_socket_id(),
+ };
+
+ TAILQ_INIT(&fdir_info->fdir_list);
+ snprintf(fdir_hash_name, RTE_HASH_NAMESIZE,
+ "fdir_%s", TDEV_NAME(eth_dev));
+ fdir_info->hash_handle = rte_hash_create(&fdir_hash_params);
+ if (!fdir_info->hash_handle) {
+ PMD_INIT_LOG(ERR, "Failed to create fdir hash table!");
+ return -EINVAL;
+ }
+ fdir_info->hash_map = rte_zmalloc("txgbe",
+ sizeof(struct txgbe_fdir_filter *) *
+ TXGBE_MAX_FDIR_FILTER_NUM,
+ 0);
+ if (!fdir_info->hash_map) {
+ PMD_INIT_LOG(ERR,
+ "Failed to allocate memory for fdir hash map!");
+ return -ENOMEM;
+ }
+ fdir_info->mask_added = FALSE;
+
+ return 0;
+}
+
static int txgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
{
struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(eth_dev);
@@ -1866,6 +1926,9 @@ txgbe_dev_close(struct rte_eth_dev *dev)
rte_free(dev->data->hash_mac_addrs);
dev->data->hash_mac_addrs = NULL;
+ /* remove all the fdir filters & hash */
+ txgbe_fdir_filter_uninit(dev);
+
/* remove all the L2 tunnel filters & hash */
txgbe_l2_tn_filter_uninit(dev);
@@ -59,8 +59,55 @@
#define TXGBE_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
#define TXGBE_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+#define TXGBE_MAX_FDIR_FILTER_NUM (1024 * 32)
#define TXGBE_MAX_L2_TN_FILTER_NUM 128
+/*
+ * Information about the fdir mode.
+ */
+struct txgbe_hw_fdir_mask {
+ uint16_t vlan_tci_mask;
+ uint32_t src_ipv4_mask;
+ uint32_t dst_ipv4_mask;
+ uint16_t src_ipv6_mask;
+ uint16_t dst_ipv6_mask;
+ uint16_t src_port_mask;
+ uint16_t dst_port_mask;
+ uint16_t flex_bytes_mask;
+ uint8_t mac_addr_byte_mask;
+ uint32_t tunnel_id_mask;
+ uint8_t tunnel_type_mask;
+};
+
+struct txgbe_fdir_filter {
+ TAILQ_ENTRY(txgbe_fdir_filter) entries;
+ struct txgbe_atr_input input; /* 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(txgbe_fdir_filter_list, txgbe_fdir_filter);
+
+struct txgbe_hw_fdir_info {
+ struct txgbe_hw_fdir_mask mask;
+ uint8_t flex_bytes_offset;
+ uint16_t collision;
+ uint16_t free;
+ uint16_t maxhash;
+ uint8_t maxlen;
+ uint64_t add;
+ uint64_t remove;
+ uint64_t f_add;
+ uint64_t f_remove;
+ struct txgbe_fdir_filter_list fdir_list; /* filter list*/
+ /* store the pointers of the filters, index is the hash value. */
+ struct txgbe_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 */
struct txgbe_interrupt {
uint32_t flags;
@@ -206,6 +253,7 @@ struct txgbe_bw_conf {
struct txgbe_adapter {
struct txgbe_hw hw;
struct txgbe_hw_stats stats;
+ struct txgbe_hw_fdir_info fdir;
struct txgbe_interrupt intr;
struct txgbe_stat_mappings stat_mappings;
struct txgbe_vfta shadow_vfta;
@@ -238,6 +286,9 @@ struct txgbe_adapter {
#define TXGBE_DEV_INTR(dev) \
(&((struct txgbe_adapter *)(dev)->data->dev_private)->intr)
+#define TXGBE_DEV_FDIR(dev) \
+ (&((struct txgbe_adapter *)(dev)->data->dev_private)->fdir)
+
#define TXGBE_DEV_STAT_MAPPINGS(dev) \
(&((struct txgbe_adapter *)(dev)->data->dev_private)->stat_mappings)