From e74a759a7273c6e9cca07c851694cb428b8a1f8c Mon Sep 17 00:00:00 2001 From: Sujith Sankar Date: Thu, 9 Apr 2015 14:59:32 +0530 Subject: [PATCH] enic: migrate flow director filtering to new API This patch helps enic migrate to the new flow-director API. It takes care of the following. 1. The change in fdir_filter structure and stats structure 2. DPDK interface functions in enic_ethdev.c 3. ENIC driver functions that deal with the VIC adapter Signed-off-by: Sujith Sankar --- lib/librte_pmd_enic/enic.h | 12 ++--- lib/librte_pmd_enic/enic_clsf.c | 43 +++++++++++++----- lib/librte_pmd_enic/enic_ethdev.c | 75 ++++++++++++++++++++----------- 3 files changed, 88 insertions(+), 42 deletions(-) diff --git a/lib/librte_pmd_enic/enic.h b/lib/librte_pmd_enic/enic.h index 0eba334231..7528d7d0be 100644 --- a/lib/librte_pmd_enic/enic.h +++ b/lib/librte_pmd_enic/enic.h @@ -80,13 +80,13 @@ #define ENICPMD_FDIR_MAX 64 struct enic_fdir_node { - struct rte_fdir_filter filter; + struct rte_eth_fdir_filter filter; u16 fltr_id; u16 rq_index; }; struct enic_fdir { - struct rte_eth_fdir stats; + struct rte_eth_fdir_stats stats; struct rte_hash *hash; struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX]; }; @@ -111,7 +111,7 @@ struct enic { pthread_t err_intr_thread; int promisc; int allmulti; - uint8_t ig_vlan_strip_en; + u8 ig_vlan_strip_en; int link_status; u8 hw_ip_checksum; @@ -155,10 +155,12 @@ static inline struct enic *pmd_priv(struct rte_eth_dev *eth_dev) return (struct enic *)eth_dev->data->dev_private; } +extern void enic_fdir_stats_get(struct enic *enic, + struct rte_eth_fdir_stats *stats); extern int enic_fdir_add_fltr(struct enic *enic, - struct rte_fdir_filter *params, u16 queue, u8 drop); + struct rte_eth_fdir_filter *params); extern int enic_fdir_del_fltr(struct enic *enic, - struct rte_fdir_filter *params); + struct rte_eth_fdir_filter *params); extern void enic_free_wq(void *txq); extern int enic_alloc_intr_resources(struct enic *enic); extern int enic_setup_finish(struct enic *enic); diff --git a/lib/librte_pmd_enic/enic_clsf.c b/lib/librte_pmd_enic/enic_clsf.c index a069194e90..937723e002 100644 --- a/lib/librte_pmd_enic/enic_clsf.c +++ b/lib/librte_pmd_enic/enic_clsf.c @@ -65,7 +65,12 @@ #define ENICPMD_CLSF_HASH_ENTRIES ENICPMD_FDIR_MAX #define ENICPMD_CLSF_BUCKET_ENTRIES 4 -int enic_fdir_del_fltr(struct enic *enic, struct rte_fdir_filter *params) +void enic_fdir_stats_get(struct enic *enic, struct rte_eth_fdir_stats *stats) +{ + *stats = enic->fdir.stats; +} + +int enic_fdir_del_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) { int32_t pos; struct enic_fdir_node *key; @@ -92,23 +97,33 @@ int enic_fdir_del_fltr(struct enic *enic, struct rte_fdir_filter *params) return 0; } -int enic_fdir_add_fltr(struct enic *enic, struct rte_fdir_filter *params, - u16 queue, u8 drop) +int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) { struct enic_fdir_node *key; struct filter fltr = {0}; int32_t pos; u8 do_free = 0; u16 old_fltr_id = 0; + u32 flowtype_supported; + u16 flex_bytes; + u16 queue; + + flowtype_supported = ( + (RTE_ETH_FLOW_NONFRAG_IPV4_TCP == params->input.flow_type) || + (RTE_ETH_FLOW_NONFRAG_IPV4_UDP == params->input.flow_type)); + + flex_bytes = ((params->input.flow_ext.flexbytes[1] << 8 & 0xFF00) | + (params->input.flow_ext.flexbytes[0] & 0xFF)); - if (!enic->fdir.hash || params->vlan_id || !params->l4type || - (RTE_FDIR_IPTYPE_IPV6 == params->iptype) || - (RTE_FDIR_L4TYPE_SCTP == params->l4type) || - params->flex_bytes || drop) { + if (!enic->fdir.hash || + (params->input.flow_ext.vlan_tci & 0xFFF) || + !flowtype_supported || flex_bytes || + params->action.behavior /* drop */) { enic->fdir.stats.f_add++; return -ENOTSUP; } + queue = params->action.rx_queue; /* See if the key is already there in the table */ pos = rte_hash_del_key(enic->fdir.hash, params); switch (pos) { @@ -168,12 +183,16 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_fdir_filter *params, key->rq_index = queue; fltr.type = FILTER_IPV4_5TUPLE; - fltr.u.ipv4.src_addr = rte_be_to_cpu_32(params->ip_src.ipv4_addr); - fltr.u.ipv4.dst_addr = rte_be_to_cpu_32(params->ip_dst.ipv4_addr); - fltr.u.ipv4.src_port = rte_be_to_cpu_16(params->port_src); - fltr.u.ipv4.dst_port = rte_be_to_cpu_16(params->port_dst); + fltr.u.ipv4.src_addr = rte_be_to_cpu_32( + params->input.flow.ip4_flow.src_ip); + fltr.u.ipv4.dst_addr = rte_be_to_cpu_32( + params->input.flow.ip4_flow.dst_ip); + fltr.u.ipv4.src_port = rte_be_to_cpu_16( + params->input.flow.udp4_flow.src_port); + fltr.u.ipv4.dst_port = rte_be_to_cpu_16( + params->input.flow.udp4_flow.dst_port); - if (RTE_FDIR_L4TYPE_TCP == params->l4type) + if (RTE_ETH_FLOW_NONFRAG_IPV4_TCP == params->input.flow_type) fltr.u.ipv4.protocol = PROTO_TCP; else fltr.u.ipv4.protocol = PROTO_UDP; diff --git a/lib/librte_pmd_enic/enic_ethdev.c b/lib/librte_pmd_enic/enic_ethdev.c index a319e1eca9..63a594d163 100644 --- a/lib/librte_pmd_enic/enic_ethdev.c +++ b/lib/librte_pmd_enic/enic_ethdev.c @@ -69,33 +69,64 @@ RTE_PCI_DEV_ID_DECL_ENIC(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_VF) {.vendor_id = 0, /* Sentinal */}, }; -static int enicpmd_fdir_remove_perfect_filter(struct rte_eth_dev *eth_dev, - struct rte_fdir_filter *fdir_filter, - __rte_unused uint16_t soft_id) +static int +enicpmd_fdir_ctrl_func(struct rte_eth_dev *eth_dev, + enum rte_filter_op filter_op, void *arg) { struct enic *enic = pmd_priv(eth_dev); + int ret = 0; ENICPMD_FUNC_TRACE(); - return enic_fdir_del_fltr(enic, fdir_filter); -} - -static int enicpmd_fdir_add_perfect_filter(struct rte_eth_dev *eth_dev, - struct rte_fdir_filter *fdir_filter, __rte_unused uint16_t soft_id, - uint8_t queue, uint8_t drop) -{ - struct enic *enic = pmd_priv(eth_dev); + if (filter_op == RTE_ETH_FILTER_NOP) + return 0; - ENICPMD_FUNC_TRACE(); - return enic_fdir_add_fltr(enic, fdir_filter, (uint16_t)queue, drop); + if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH) + return -EINVAL; + + switch (filter_op) { + case RTE_ETH_FILTER_ADD: + case RTE_ETH_FILTER_UPDATE: + ret = enic_fdir_add_fltr(enic, + (struct rte_eth_fdir_filter *)arg); + break; + + case RTE_ETH_FILTER_DELETE: + ret = enic_fdir_del_fltr(enic, + (struct rte_eth_fdir_filter *)arg); + break; + + case RTE_ETH_FILTER_STATS: + enic_fdir_stats_get(enic, (struct rte_eth_fdir_stats *)arg); + break; + + case RTE_ETH_FILTER_FLUSH: + case RTE_ETH_FILTER_INFO: + dev_warning(enic, "unsupported operation %u", filter_op); + ret = -ENOTSUP; + break; + default: + dev_err(enic, "unknown operation %u", filter_op); + ret = -EINVAL; + break; + } + return ret; } -static void enicpmd_fdir_info_get(struct rte_eth_dev *eth_dev, - struct rte_eth_fdir *fdir) +static int +enicpmd_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) { - struct enic *enic = pmd_priv(eth_dev); + int ret = -EINVAL; - ENICPMD_FUNC_TRACE(); - *fdir = enic->fdir.stats; + if (RTE_ETH_FILTER_FDIR == filter_type) + ret = enicpmd_fdir_ctrl_func(dev, filter_op, arg); + else + dev_warning(enic, "Filter type (%d) not supported", + filter_type); + + return ret; } static void enicpmd_dev_tx_queue_release(void *txq) @@ -545,14 +576,8 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = { .priority_flow_ctrl_set = NULL, .mac_addr_add = enicpmd_add_mac_addr, .mac_addr_remove = enicpmd_remove_mac_addr, - .fdir_add_signature_filter = NULL, - .fdir_update_signature_filter = NULL, - .fdir_remove_signature_filter = NULL, - .fdir_infos_get = enicpmd_fdir_info_get, - .fdir_add_perfect_filter = enicpmd_fdir_add_perfect_filter, - .fdir_update_perfect_filter = enicpmd_fdir_add_perfect_filter, - .fdir_remove_perfect_filter = enicpmd_fdir_remove_perfect_filter, .fdir_set_masks = NULL, + .filter_ctrl = enicpmd_dev_filter_ctrl, }; struct enic *enicpmd_list_head = NULL; -- 2.20.1