From fd9485d62a78e027b107717476a9b0df005a012d Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Sun, 11 Dec 2016 13:56:24 +0200 Subject: Cisco VIC card - support for receive all mode, and work around for IPv6 issues Signed-off-by: Ido Barnea --- src/dpdk/drivers/net/enic/base/vnic_dev.c | 5 +++ src/dpdk/drivers/net/enic/enic_clsf.c | 55 +++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) (limited to 'src/dpdk') diff --git a/src/dpdk/drivers/net/enic/base/vnic_dev.c b/src/dpdk/drivers/net/enic/base/vnic_dev.c index 713b6089..e50b90e7 100644 --- a/src/dpdk/drivers/net/enic/base/vnic_dev.c +++ b/src/dpdk/drivers/net/enic/base/vnic_dev.c @@ -667,7 +667,12 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); +#define TREX_PATCH +#ifdef TREX_PATCH + err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); +#else err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); +#endif if (err) pr_err("Can't set packet filter\n"); diff --git a/src/dpdk/drivers/net/enic/enic_clsf.c b/src/dpdk/drivers/net/enic/enic_clsf.c index 23cb0124..8f68faab 100644 --- a/src/dpdk/drivers/net/enic/enic_clsf.c +++ b/src/dpdk/drivers/net/enic/enic_clsf.c @@ -107,6 +107,7 @@ enic_set_layer(struct filter_generic_1 *gp, unsigned int flag, memcpy(gp->layer[layer].val, val, len); } + /* Copy Flow Director filter to a VIC ipv4 filter (for Cisco VICs * without advanced filter support. */ @@ -132,6 +133,28 @@ copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, fltr->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE; } +#define TREX_PATCH +#ifdef TREX_PATCH +void +copy_fltr_recv_all(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, + struct rte_eth_fdir_masks *masks) { + struct filter_generic_1 *gp = &fltr->u.generic_1; + memset(gp, 0, sizeof(*gp)); + + struct ether_hdr eth_mask, eth_val; + memset(ð_mask, 0, sizeof(eth_mask)); + memset(ð_val, 0, sizeof(eth_val)); + + eth_val.ether_type = 0x0806; + eth_mask.ether_type = 0; + + gp->position = 0; + enic_set_layer(gp, 0, FILTER_GENERIC_1_L2, + ð_mask, ð_val, sizeof(struct ether_hdr)); + +} +#endif + /* Copy Flow Director filter to a VIC generic filter (requires advanced * filter support. */ @@ -146,6 +169,11 @@ copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, fltr->type = FILTER_DPDK_1; memset(gp, 0, sizeof(*gp)); +#ifdef TREX_PATCH + // important for this to be below 2. + // If added with position 2, IPv6 UDP and ICMP seems to be caught by some other rule + gp->position = 1; +#endif if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) { struct udp_hdr udp_mask, udp_val; @@ -344,11 +372,23 @@ int enic_fdir_del_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) case -EINVAL: case -ENOENT: enic->fdir.stats.f_remove++; +#ifdef TREX_PATCH + return pos; +#else return -EINVAL; +#endif default: /* The entry is present in the table */ key = enic->fdir.nodes[pos]; +#ifdef TREX_PATCH + switch (params->soft_id) { + case 100: + // remove promisc when we delete 'receive all' filter + vnic_dev_packet_filter(enic->vdev, 1, 1, 1, 0, 1); + break; + } +#endif /* Delete the filter */ vnic_dev_classifier(enic->vdev, CLSF_DEL, &key->fltr_id, NULL); @@ -455,8 +495,19 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) key->filter = *params; key->rq_index = queue; - enic->fdir.copy_fltr_fn(&fltr, ¶ms->input, - &enic->rte_dev->data->dev_conf.fdir_conf.mask); +#ifdef TREX_PATCH + switch (params->soft_id) { + case 100: + vnic_dev_packet_filter(enic->vdev, 1, 1, 1, 1, 1); + copy_fltr_recv_all(&fltr, ¶ms->input, &enic->rte_dev->data->dev_conf.fdir_conf.mask); + break; + default: +#endif + enic->fdir.copy_fltr_fn(&fltr, ¶ms->input, + &enic->rte_dev->data->dev_conf.fdir_conf.mask); +#ifdef TREX_PATCH + } +#endif if (!vnic_dev_classifier(enic->vdev, CLSF_ADD, &queue, &fltr)) { key->fltr_id = queue; -- cgit 1.2.3-korg