diff options
author | Amir Vadai | 2016-03-08 11:42:36 +0100 |
---|---|---|
committer | David S. Miller | 2016-03-10 22:24:02 +0100 |
commit | e8f887ac6a45ecb7f881f278a3fed1fbf002ef0b (patch) | |
tree | 9697ce4e5e8af43e6c988fafb1977e31205b1b72 /drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |
parent | net/mlx5e: Add a new priority for kernel flow tables (diff) | |
download | kernel-qcow2-linux-e8f887ac6a45ecb7f881f278a3fed1fbf002ef0b.tar.gz kernel-qcow2-linux-e8f887ac6a45ecb7f881f278a3fed1fbf002ef0b.tar.xz kernel-qcow2-linux-e8f887ac6a45ecb7f881f278a3fed1fbf002ef0b.zip |
net/mlx5e: Introduce tc offload support
Extend ndo_setup_tc() to support ingress tc offloading. Will be used by
later patches to offload tc flower filter.
Feature is off by default and could be enabled by issuing:
# ethtool -K eth0 hw-tc-offload on
Offloads flow table is dynamically created when first filter is
added.
Rules are saved in a hash table that is maintained by the consumer (for
example - the flower offload in the next patch).
When last filter is removed and no filters exist in the hash table, the
offload flow table is destroyed.
Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en_main.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index f1ebe065de0d..e6210485e128 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -30,9 +30,12 @@ * SOFTWARE. */ +#include <net/tc_act/tc_gact.h> +#include <net/pkt_cls.h> #include <linux/mlx5/fs.h> #include <net/vxlan.h> #include "en.h" +#include "en_tc.h" #include "eswitch.h" #include "vxlan.h" @@ -1883,6 +1886,17 @@ static int mlx5e_setup_tc(struct net_device *netdev, u8 tc) static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle, __be16 proto, struct tc_to_netdev *tc) { + struct mlx5e_priv *priv = netdev_priv(dev); + + if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS)) + goto mqprio; + + switch (tc->type) { + default: + return -EOPNOTSUPP; + } + +mqprio: if (tc->type != TC_SETUP_MQPRIO) return -EINVAL; @@ -1968,6 +1982,13 @@ static int mlx5e_set_features(struct net_device *netdev, mlx5e_disable_vlan_filter(priv); } + if ((changes & NETIF_F_HW_TC) && !(features & NETIF_F_HW_TC) && + mlx5e_tc_num_filters(priv)) { + netdev_err(netdev, + "Active offloaded tc filters, can't turn hw_tc_offload off\n"); + return -EINVAL; + } + return err; } @@ -2375,6 +2396,13 @@ static void mlx5e_build_netdev(struct net_device *netdev) if (!priv->params.lro_en) netdev->features &= ~NETIF_F_LRO; +#define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f) + if (FT_CAP(flow_modify_en) && + FT_CAP(modify_root) && + FT_CAP(identified_miss_table_mode) && + FT_CAP(flow_table_modify)) + priv->netdev->hw_features |= NETIF_F_HW_TC; + netdev->features |= NETIF_F_HIGHDMA; netdev->priv_flags |= IFF_UNICAST_FLT; @@ -2496,6 +2524,10 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) mlx5e_vxlan_init(priv); + err = mlx5e_tc_init(priv); + if (err) + goto err_destroy_flow_tables; + #ifdef CONFIG_MLX5_CORE_EN_DCB mlx5e_dcbnl_ieee_setets_core(priv, &priv->params.ets); #endif @@ -2503,7 +2535,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) err = register_netdev(netdev); if (err) { mlx5_core_err(mdev, "register_netdev failed, %d\n", err); - goto err_destroy_flow_tables; + goto err_tc_cleanup; } if (mlx5e_vxlan_allowed(mdev)) @@ -2514,6 +2546,9 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) return priv; +err_tc_cleanup: + mlx5e_tc_cleanup(priv); + err_destroy_flow_tables: mlx5e_destroy_flow_tables(priv); @@ -2561,6 +2596,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) mlx5e_disable_async_events(priv); flush_scheduled_work(); unregister_netdev(netdev); + mlx5e_tc_cleanup(priv); mlx5e_vxlan_cleanup(priv); mlx5e_destroy_flow_tables(priv); mlx5e_destroy_tirs(priv); |