diff options
author | Manish Chopra <manish.chopra@cavium.com> | 2018-05-24 19:54:51 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-25 23:10:42 +0300 |
commit | 3893fc62b1769db3ef160f7f1e36d3db754497ee (patch) | |
tree | 348383b96ad89169a04c355acc5031b843236f01 /drivers | |
parent | 89ffd14ee95dca812874fcd25ad3538ff3592a49 (diff) | |
download | linux-3893fc62b1769db3ef160f7f1e36d3db754497ee.tar.xz |
qed*: Support other classification modes.
Currently, driver supports flow classification to PF
receive queues based on TCP/UDP 4 tuples [src_ip, dst_ip,
src_port, dst_port] only.
This patch enables to configure different flow profiles
[For example - only UDP dest port or src_ip based] on the
adapter so that classification can be done according to
just those fields as well. Although, at a time just one
type of flow configuration is supported due to limited
number of flow profiles available on the device.
For example -
ethtool -N enp7s0f0 flow-type udp4 dst-port 45762 action 2
ethtool -N enp7s0f0 flow-type tcp4 src-ip 192.16.4.10 action 1
ethtool -N enp7s0f0 flow-type udp6 dst-port 45762 action 3
Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_l2.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_filter.c | 31 |
2 files changed, 31 insertions, 2 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c index 5e655c3601cf..3cb8a8088467 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c @@ -1973,6 +1973,8 @@ qed_arfs_mode_to_hsi(enum qed_filter_config_mode mode) return GFT_PROFILE_TYPE_4_TUPLE; if (mode == QED_FILTER_CONFIG_MODE_IP_DEST) return GFT_PROFILE_TYPE_IP_DST_ADDR; + if (mode == QED_FILTER_CONFIG_MODE_IP_SRC) + return GFT_PROFILE_TYPE_IP_SRC_ADDR; return GFT_PROFILE_TYPE_L4_DST_PORT; } diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 43ed420900c1..9b84f0cb12e7 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1623,9 +1623,17 @@ static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev, t->src_port = fs->h_u.tcp_ip4_spec.psrc; t->dst_port = fs->h_u.tcp_ip4_spec.pdst; - /* We must have a valid 4-tuple */ + /* We must either have a valid 4-tuple or only dst port + * or only src ip as an input + */ if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) { t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE; + } else if (!t->src_port && t->dst_port && + !t->src_ipv4 && !t->dst_ipv4) { + t->mode = QED_FILTER_CONFIG_MODE_L4_PORT; + } else if (!t->src_port && !t->dst_port && + !t->dst_ipv4 && t->src_ipv4) { + t->mode = QED_FILTER_CONFIG_MODE_IP_SRC; } else { DP_INFO(edev, "Invalid N-tuple\n"); return -EOPNOTSUPP; @@ -1697,11 +1705,21 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev, t->src_port = fs->h_u.tcp_ip6_spec.psrc; t->dst_port = fs->h_u.tcp_ip6_spec.pdst; - /* We must make sure we have a valid 4-tuple */ + /* We must make sure we have a valid 4-tuple or only dest port + * or only src ip as an input + */ if (t->src_port && t->dst_port && memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) && memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) { t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE; + } else if (!t->src_port && t->dst_port && + !memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) && + !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) { + t->mode = QED_FILTER_CONFIG_MODE_L4_PORT; + } else if (!t->src_port && !t->dst_port && + !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr)) && + memcmp(&t->src_ipv6, p, sizeof(struct in6_addr))) { + t->mode = QED_FILTER_CONFIG_MODE_IP_SRC; } else { DP_INFO(edev, "Invalid N-tuple\n"); return -EOPNOTSUPP; @@ -1779,6 +1797,15 @@ static int qede_flow_spec_validate(struct qede_dev *edev, return -EINVAL; } + /* Check if the filtering-mode could support the filter */ + if (edev->arfs->filter_count && + edev->arfs->mode != t->mode) { + DP_INFO(edev, + "flow_spec would require filtering mode %08x, but %08x is configured\n", + t->mode, edev->arfs->filter_count); + return -EINVAL; + } + if (fs->ring_cookie >= QEDE_RSS_COUNT(edev)) { DP_INFO(edev, "Queue out-of-bounds\n"); return -EINVAL; |