aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGal Pressman <galp@mellanox.com>2017-08-13 09:22:38 -0400
committerSaeed Mahameed <saeedm@mellanox.com>2017-08-30 18:54:15 -0400
commit7b3722fa9ef647eb1ae6a60a5d46f7c67ab09a33 (patch)
tree92bfb028b90bb556d8684162cc309583ebeceb0d
parent2729984149e6a23e849a40e16fc3efdc07dd3668 (diff)
net/mlx5e: Support RSS for GRE tunneled packets
Introduce a new flow table and indirect TIRs which are used to hash the inner packet headers of GRE tunneled packets. When a GRE tunneled packet is received, the TTC flow table will match the new IPv4/6->GRE rules which will forward it to the inner TTC table. The inner TTC is similar to its counterpart outer TTC table, but matching the inner packet headers instead of the outer ones (and does not include the new IPv4/6->GRE rules). The new rules will not add steering hops since they are added to an already existing flow group which will be matched regardless of this patch. Non GRE traffic will not be affected. The inner flow table will forward the packet to inner indirect TIRs which hash the inner packet and thus result in RSS for the tunneled packets. Testing 8 TCP streams bandwidth over GRE: System: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz NIC: Mellanox Technologies MT28800 Family [ConnectX-5 Ex] Before: 21.3 Gbps (Single RQ) Now : 90.5 Gbps (RSS spread on 8 RQs) Signed-off-by: Gal Pressman <galp@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs.c248
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c57
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c4
5 files changed, 321 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 0039b4725405..a31912415264 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -620,6 +620,12 @@ enum mlx5e_traffic_types {
620 MLX5E_NUM_INDIR_TIRS = MLX5E_TT_ANY, 620 MLX5E_NUM_INDIR_TIRS = MLX5E_TT_ANY,
621}; 621};
622 622
623enum mlx5e_tunnel_types {
624 MLX5E_TT_IPV4_GRE,
625 MLX5E_TT_IPV6_GRE,
626 MLX5E_NUM_TUNNEL_TT,
627};
628
623enum { 629enum {
624 MLX5E_STATE_ASYNC_EVENTS_ENABLED, 630 MLX5E_STATE_ASYNC_EVENTS_ENABLED,
625 MLX5E_STATE_OPENED, 631 MLX5E_STATE_OPENED,
@@ -679,6 +685,7 @@ struct mlx5e_l2_table {
679struct mlx5e_ttc_table { 685struct mlx5e_ttc_table {
680 struct mlx5e_flow_table ft; 686 struct mlx5e_flow_table ft;
681 struct mlx5_flow_handle *rules[MLX5E_NUM_TT]; 687 struct mlx5_flow_handle *rules[MLX5E_NUM_TT];
688 struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
682}; 689};
683 690
684#define ARFS_HASH_SHIFT BITS_PER_BYTE 691#define ARFS_HASH_SHIFT BITS_PER_BYTE
@@ -711,6 +718,7 @@ enum {
711 MLX5E_VLAN_FT_LEVEL = 0, 718 MLX5E_VLAN_FT_LEVEL = 0,
712 MLX5E_L2_FT_LEVEL, 719 MLX5E_L2_FT_LEVEL,
713 MLX5E_TTC_FT_LEVEL, 720 MLX5E_TTC_FT_LEVEL,
721 MLX5E_INNER_TTC_FT_LEVEL,
714 MLX5E_ARFS_FT_LEVEL 722 MLX5E_ARFS_FT_LEVEL
715}; 723};
716 724
@@ -736,6 +744,7 @@ struct mlx5e_flow_steering {
736 struct mlx5e_vlan_table vlan; 744 struct mlx5e_vlan_table vlan;
737 struct mlx5e_l2_table l2; 745 struct mlx5e_l2_table l2;
738 struct mlx5e_ttc_table ttc; 746 struct mlx5e_ttc_table ttc;
747 struct mlx5e_ttc_table inner_ttc;
739 struct mlx5e_arfs_tables arfs; 748 struct mlx5e_arfs_tables arfs;
740}; 749};
741 750
@@ -769,6 +778,7 @@ struct mlx5e_priv {
769 u32 tisn[MLX5E_MAX_NUM_TC]; 778 u32 tisn[MLX5E_MAX_NUM_TC];
770 struct mlx5e_rqt indir_rqt; 779 struct mlx5e_rqt indir_rqt;
771 struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS]; 780 struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
781 struct mlx5e_tir inner_indir_tir[MLX5E_NUM_INDIR_TIRS];
772 struct mlx5e_tir direct_tir[MLX5E_MAX_NUM_CHANNELS]; 782 struct mlx5e_tir direct_tir[MLX5E_MAX_NUM_CHANNELS];
773 u32 tx_rates[MLX5E_MAX_NUM_SQS]; 783 u32 tx_rates[MLX5E_MAX_NUM_SQS];
774 int hard_mtu; 784 int hard_mtu;
@@ -903,7 +913,7 @@ int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz,
903 struct mlx5e_redirect_rqt_param rrp); 913 struct mlx5e_redirect_rqt_param rrp);
904void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params, 914void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,
905 enum mlx5e_traffic_types tt, 915 enum mlx5e_traffic_types tt,
906 void *tirc); 916 void *tirc, bool inner);
907 917
908int mlx5e_open_locked(struct net_device *netdev); 918int mlx5e_open_locked(struct net_device *netdev);
909int mlx5e_close_locked(struct net_device *netdev); 919int mlx5e_close_locked(struct net_device *netdev);
@@ -932,6 +942,12 @@ void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
932void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, 942void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
933 struct mlx5e_params *params, u8 rq_type); 943 struct mlx5e_params *params, u8 rq_type);
934 944
945static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
946{
947 return (MLX5_CAP_ETH(mdev, tunnel_stateless_gre) &&
948 MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
949}
950
935static inline 951static inline
936struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc) 952struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
937{ 953{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 0dd7e9caf150..c6ec90e9c95b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1212,9 +1212,18 @@ static void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
1212 1212
1213 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 1213 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
1214 memset(tirc, 0, ctxlen); 1214 memset(tirc, 0, ctxlen);
1215 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc); 1215 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, false);
1216 mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen); 1216 mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen);
1217 } 1217 }
1218
1219 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
1220 return;
1221
1222 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
1223 memset(tirc, 0, ctxlen);
1224 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true);
1225 mlx5_core_modify_tir(mdev, priv->inner_indir_tir[tt].tirn, in, inlen);
1226 }
1218} 1227}
1219 1228
1220static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir, 1229static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 85e6226dacfb..f11fd07ac4dd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -608,12 +608,21 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
608 ttc->rules[i] = NULL; 608 ttc->rules[i] = NULL;
609 } 609 }
610 } 610 }
611
612 for (i = 0; i < MLX5E_NUM_TUNNEL_TT; i++) {
613 if (!IS_ERR_OR_NULL(ttc->tunnel_rules[i])) {
614 mlx5_del_flow_rules(ttc->tunnel_rules[i]);
615 ttc->tunnel_rules[i] = NULL;
616 }
617 }
611} 618}
612 619
613static struct { 620struct mlx5e_etype_proto {
614 u16 etype; 621 u16 etype;
615 u8 proto; 622 u8 proto;
616} ttc_rules[] = { 623};
624
625static struct mlx5e_etype_proto ttc_rules[] = {
617 [MLX5E_TT_IPV4_TCP] = { 626 [MLX5E_TT_IPV4_TCP] = {
618 .etype = ETH_P_IP, 627 .etype = ETH_P_IP,
619 .proto = IPPROTO_TCP, 628 .proto = IPPROTO_TCP,
@@ -660,6 +669,17 @@ static struct {
660 }, 669 },
661}; 670};
662 671
672static struct mlx5e_etype_proto ttc_tunnel_rules[] = {
673 [MLX5E_TT_IPV4_GRE] = {
674 .etype = ETH_P_IP,
675 .proto = IPPROTO_GRE,
676 },
677 [MLX5E_TT_IPV6_GRE] = {
678 .etype = ETH_P_IPV6,
679 .proto = IPPROTO_GRE,
680 },
681};
682
663static u8 mlx5e_etype_to_ipv(u16 ethertype) 683static u8 mlx5e_etype_to_ipv(u16 ethertype)
664{ 684{
665 if (ethertype == ETH_P_IP) 685 if (ethertype == ETH_P_IP)
@@ -742,6 +762,20 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv)
742 goto del_rules; 762 goto del_rules;
743 } 763 }
744 764
765 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
766 return 0;
767
768 rules = ttc->tunnel_rules;
769 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
770 dest.ft = priv->fs.inner_ttc.ft.t;
771 for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
772 rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
773 ttc_tunnel_rules[tt].etype,
774 ttc_tunnel_rules[tt].proto);
775 if (IS_ERR(rules[tt]))
776 goto del_rules;
777 }
778
745 return 0; 779 return 0;
746 780
747del_rules: 781del_rules:
@@ -752,13 +786,21 @@ del_rules:
752} 786}
753 787
754#define MLX5E_TTC_NUM_GROUPS 3 788#define MLX5E_TTC_NUM_GROUPS 3
755#define MLX5E_TTC_GROUP1_SIZE BIT(3) 789#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT)
756#define MLX5E_TTC_GROUP2_SIZE BIT(1) 790#define MLX5E_TTC_GROUP2_SIZE BIT(1)
757#define MLX5E_TTC_GROUP3_SIZE BIT(0) 791#define MLX5E_TTC_GROUP3_SIZE BIT(0)
758#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ 792#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\
759 MLX5E_TTC_GROUP2_SIZE +\ 793 MLX5E_TTC_GROUP2_SIZE +\
760 MLX5E_TTC_GROUP3_SIZE) 794 MLX5E_TTC_GROUP3_SIZE)
761 795
796#define MLX5E_INNER_TTC_NUM_GROUPS 3
797#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3)
798#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1)
799#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0)
800#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\
801 MLX5E_INNER_TTC_GROUP2_SIZE +\
802 MLX5E_INNER_TTC_GROUP3_SIZE)
803
762static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, 804static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc,
763 bool use_ipv) 805 bool use_ipv)
764{ 806{
@@ -826,6 +868,190 @@ err:
826 return err; 868 return err;
827} 869}
828 870
871static struct mlx5_flow_handle *
872mlx5e_generate_inner_ttc_rule(struct mlx5e_priv *priv,
873 struct mlx5_flow_table *ft,
874 struct mlx5_flow_destination *dest,
875 u16 etype, u8 proto)
876{
877 MLX5_DECLARE_FLOW_ACT(flow_act);
878 struct mlx5_flow_handle *rule;
879 struct mlx5_flow_spec *spec;
880 int err = 0;
881 u8 ipv;
882
883 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
884 if (!spec)
885 return ERR_PTR(-ENOMEM);
886
887 ipv = mlx5e_etype_to_ipv(etype);
888 if (etype && ipv) {
889 spec->match_criteria_enable = MLX5_MATCH_INNER_HEADERS;
890 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, inner_headers.ip_version);
891 MLX5_SET(fte_match_param, spec->match_value, inner_headers.ip_version, ipv);
892 }
893
894 if (proto) {
895 spec->match_criteria_enable = MLX5_MATCH_INNER_HEADERS;
896 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, inner_headers.ip_protocol);
897 MLX5_SET(fte_match_param, spec->match_value, inner_headers.ip_protocol, proto);
898 }
899
900 rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, 1);
901 if (IS_ERR(rule)) {
902 err = PTR_ERR(rule);
903 netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
904 }
905
906 kvfree(spec);
907 return err ? ERR_PTR(err) : rule;
908}
909
910static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv)
911{
912 struct mlx5_flow_destination dest;
913 struct mlx5_flow_handle **rules;
914 struct mlx5e_ttc_table *ttc;
915 struct mlx5_flow_table *ft;
916 int err;
917 int tt;
918
919 ttc = &priv->fs.inner_ttc;
920 ft = ttc->ft.t;
921 rules = ttc->rules;
922
923 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
924 for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
925 if (tt == MLX5E_TT_ANY)
926 dest.tir_num = priv->direct_tir[0].tirn;
927 else
928 dest.tir_num = priv->inner_indir_tir[tt].tirn;
929
930 rules[tt] = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
931 ttc_rules[tt].etype,
932 ttc_rules[tt].proto);
933 if (IS_ERR(rules[tt]))
934 goto del_rules;
935 }
936
937 return 0;
938
939del_rules:
940 err = PTR_ERR(rules[tt]);
941 rules[tt] = NULL;
942 mlx5e_cleanup_ttc_rules(ttc);
943 return err;
944}
945
946static int mlx5e_create_inner_ttc_table_groups(struct mlx5e_ttc_table *ttc)
947{
948 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
949 struct mlx5e_flow_table *ft = &ttc->ft;
950 int ix = 0;
951 u32 *in;
952 int err;
953 u8 *mc;
954
955 ft->g = kcalloc(MLX5E_INNER_TTC_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
956 if (!ft->g)
957 return -ENOMEM;
958 in = kvzalloc(inlen, GFP_KERNEL);
959 if (!in) {
960 kfree(ft->g);
961 return -ENOMEM;
962 }
963
964 /* L4 Group */
965 mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
966 MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ip_protocol);
967 MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ip_version);
968 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_INNER_HEADERS);
969 MLX5_SET_CFG(in, start_flow_index, ix);
970 ix += MLX5E_INNER_TTC_GROUP1_SIZE;
971 MLX5_SET_CFG(in, end_flow_index, ix - 1);
972 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
973 if (IS_ERR(ft->g[ft->num_groups]))
974 goto err;
975 ft->num_groups++;
976
977 /* L3 Group */
978 MLX5_SET(fte_match_param, mc, inner_headers.ip_protocol, 0);
979 MLX5_SET_CFG(in, start_flow_index, ix);
980 ix += MLX5E_INNER_TTC_GROUP2_SIZE;
981 MLX5_SET_CFG(in, end_flow_index, ix - 1);
982 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
983 if (IS_ERR(ft->g[ft->num_groups]))
984 goto err;
985 ft->num_groups++;
986
987 /* Any Group */
988 memset(in, 0, inlen);
989 MLX5_SET_CFG(in, start_flow_index, ix);
990 ix += MLX5E_INNER_TTC_GROUP3_SIZE;
991 MLX5_SET_CFG(in, end_flow_index, ix - 1);
992 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
993 if (IS_ERR(ft->g[ft->num_groups]))
994 goto err;
995 ft->num_groups++;
996
997 kvfree(in);
998 return 0;
999
1000err:
1001 err = PTR_ERR(ft->g[ft->num_groups]);
1002 ft->g[ft->num_groups] = NULL;
1003 kvfree(in);
1004
1005 return err;
1006}
1007
1008static int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv)
1009{
1010 struct mlx5e_ttc_table *ttc = &priv->fs.inner_ttc;
1011 struct mlx5_flow_table_attr ft_attr = {};
1012 struct mlx5e_flow_table *ft = &ttc->ft;
1013 int err;
1014
1015 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
1016 return 0;
1017
1018 ft_attr.max_fte = MLX5E_INNER_TTC_TABLE_SIZE;
1019 ft_attr.level = MLX5E_INNER_TTC_FT_LEVEL;
1020 ft_attr.prio = MLX5E_NIC_PRIO;
1021
1022 ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
1023 if (IS_ERR(ft->t)) {
1024 err = PTR_ERR(ft->t);
1025 ft->t = NULL;
1026 return err;
1027 }
1028
1029 err = mlx5e_create_inner_ttc_table_groups(ttc);
1030 if (err)
1031 goto err;
1032
1033 err = mlx5e_generate_inner_ttc_table_rules(priv);
1034 if (err)
1035 goto err;
1036
1037 return 0;
1038
1039err:
1040 mlx5e_destroy_flow_table(ft);
1041 return err;
1042}
1043
1044static void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv)
1045{
1046 struct mlx5e_ttc_table *ttc = &priv->fs.inner_ttc;
1047
1048 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
1049 return;
1050
1051 mlx5e_cleanup_ttc_rules(ttc);
1052 mlx5e_destroy_flow_table(&ttc->ft);
1053}
1054
829void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv) 1055void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
830{ 1056{
831 struct mlx5e_ttc_table *ttc = &priv->fs.ttc; 1057 struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
@@ -1179,11 +1405,18 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
1179 priv->netdev->hw_features &= ~NETIF_F_NTUPLE; 1405 priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
1180 } 1406 }
1181 1407
1408 err = mlx5e_create_inner_ttc_table(priv);
1409 if (err) {
1410 netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
1411 err);
1412 goto err_destroy_arfs_tables;
1413 }
1414
1182 err = mlx5e_create_ttc_table(priv); 1415 err = mlx5e_create_ttc_table(priv);
1183 if (err) { 1416 if (err) {
1184 netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n", 1417 netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
1185 err); 1418 err);
1186 goto err_destroy_arfs_tables; 1419 goto err_destroy_inner_ttc_table;
1187 } 1420 }
1188 1421
1189 err = mlx5e_create_l2_table(priv); 1422 err = mlx5e_create_l2_table(priv);
@@ -1208,6 +1441,8 @@ err_destroy_l2_table:
1208 mlx5e_destroy_l2_table(priv); 1441 mlx5e_destroy_l2_table(priv);
1209err_destroy_ttc_table: 1442err_destroy_ttc_table:
1210 mlx5e_destroy_ttc_table(priv); 1443 mlx5e_destroy_ttc_table(priv);
1444err_destroy_inner_ttc_table:
1445 mlx5e_destroy_inner_ttc_table(priv);
1211err_destroy_arfs_tables: 1446err_destroy_arfs_tables:
1212 mlx5e_arfs_destroy_tables(priv); 1447 mlx5e_arfs_destroy_tables(priv);
1213 1448
@@ -1219,6 +1454,7 @@ void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv)
1219 mlx5e_destroy_vlan_table(priv); 1454 mlx5e_destroy_vlan_table(priv);
1220 mlx5e_destroy_l2_table(priv); 1455 mlx5e_destroy_l2_table(priv);
1221 mlx5e_destroy_ttc_table(priv); 1456 mlx5e_destroy_ttc_table(priv);
1457 mlx5e_destroy_inner_ttc_table(priv);
1222 mlx5e_arfs_destroy_tables(priv); 1458 mlx5e_arfs_destroy_tables(priv);
1223 mlx5e_ethtool_cleanup_steering(priv); 1459 mlx5e_ethtool_cleanup_steering(priv);
1224} 1460}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 9475fb89a744..111c7523d448 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2349,9 +2349,10 @@ static void mlx5e_build_tir_ctx_lro(struct mlx5e_params *params, void *tirc)
2349 2349
2350void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params, 2350void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,
2351 enum mlx5e_traffic_types tt, 2351 enum mlx5e_traffic_types tt,
2352 void *tirc) 2352 void *tirc, bool inner)
2353{ 2353{
2354 void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer); 2354 void *hfso = inner ? MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner) :
2355 MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
2355 2356
2356#define MLX5_HASH_IP (MLX5_HASH_FIELD_SEL_SRC_IP |\ 2357#define MLX5_HASH_IP (MLX5_HASH_FIELD_SEL_SRC_IP |\
2357 MLX5_HASH_FIELD_SEL_DST_IP) 2358 MLX5_HASH_FIELD_SEL_DST_IP)
@@ -2500,6 +2501,21 @@ free_in:
2500 return err; 2501 return err;
2501} 2502}
2502 2503
2504static void mlx5e_build_inner_indir_tir_ctx(struct mlx5e_priv *priv,
2505 enum mlx5e_traffic_types tt,
2506 u32 *tirc)
2507{
2508 MLX5_SET(tirc, tirc, transport_domain, priv->mdev->mlx5e_res.td.tdn);
2509
2510 mlx5e_build_tir_ctx_lro(&priv->channels.params, tirc);
2511
2512 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
2513 MLX5_SET(tirc, tirc, indirect_table, priv->indir_rqt.rqtn);
2514 MLX5_SET(tirc, tirc, tunneled_offload_en, 0x1);
2515
2516 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true);
2517}
2518
2503static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) 2519static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu)
2504{ 2520{
2505 struct mlx5_core_dev *mdev = priv->mdev; 2521 struct mlx5_core_dev *mdev = priv->mdev;
@@ -2865,7 +2881,7 @@ static void mlx5e_build_indir_tir_ctx(struct mlx5e_priv *priv,
2865 2881
2866 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT); 2882 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
2867 MLX5_SET(tirc, tirc, indirect_table, priv->indir_rqt.rqtn); 2883 MLX5_SET(tirc, tirc, indirect_table, priv->indir_rqt.rqtn);
2868 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc); 2884 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, false);
2869} 2885}
2870 2886
2871static void mlx5e_build_direct_tir_ctx(struct mlx5e_priv *priv, u32 rqtn, u32 *tirc) 2887static void mlx5e_build_direct_tir_ctx(struct mlx5e_priv *priv, u32 rqtn, u32 *tirc)
@@ -2884,6 +2900,7 @@ int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv)
2884 struct mlx5e_tir *tir; 2900 struct mlx5e_tir *tir;
2885 void *tirc; 2901 void *tirc;
2886 int inlen; 2902 int inlen;
2903 int i = 0;
2887 int err; 2904 int err;
2888 u32 *in; 2905 u32 *in;
2889 int tt; 2906 int tt;
@@ -2899,16 +2916,36 @@ int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv)
2899 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx); 2916 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
2900 mlx5e_build_indir_tir_ctx(priv, tt, tirc); 2917 mlx5e_build_indir_tir_ctx(priv, tt, tirc);
2901 err = mlx5e_create_tir(priv->mdev, tir, in, inlen); 2918 err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
2902 if (err) 2919 if (err) {
2903 goto err_destroy_tirs; 2920 mlx5_core_warn(priv->mdev, "create indirect tirs failed, %d\n", err);
2921 goto err_destroy_inner_tirs;
2922 }
2904 } 2923 }
2905 2924
2925 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
2926 goto out;
2927
2928 for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) {
2929 memset(in, 0, inlen);
2930 tir = &priv->inner_indir_tir[i];
2931 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
2932 mlx5e_build_inner_indir_tir_ctx(priv, i, tirc);
2933 err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
2934 if (err) {
2935 mlx5_core_warn(priv->mdev, "create inner indirect tirs failed, %d\n", err);
2936 goto err_destroy_inner_tirs;
2937 }
2938 }
2939
2940out:
2906 kvfree(in); 2941 kvfree(in);
2907 2942
2908 return 0; 2943 return 0;
2909 2944
2910err_destroy_tirs: 2945err_destroy_inner_tirs:
2911 mlx5_core_warn(priv->mdev, "create indirect tirs failed, %d\n", err); 2946 for (i--; i >= 0; i--)
2947 mlx5e_destroy_tir(priv->mdev, &priv->inner_indir_tir[i]);
2948
2912 for (tt--; tt >= 0; tt--) 2949 for (tt--; tt >= 0; tt--)
2913 mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]); 2950 mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]);
2914 2951
@@ -2962,6 +2999,12 @@ void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv)
2962 2999
2963 for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) 3000 for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
2964 mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]); 3001 mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]);
3002
3003 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
3004 return;
3005
3006 for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
3007 mlx5e_destroy_tir(priv->mdev, &priv->inner_indir_tir[i]);
2965} 3008}
2966 3009
2967void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv) 3010void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index d731d57a996a..5a7bea688ec8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -83,8 +83,8 @@
83#define ETHTOOL_PRIO_NUM_LEVELS 1 83#define ETHTOOL_PRIO_NUM_LEVELS 1
84#define ETHTOOL_NUM_PRIOS 11 84#define ETHTOOL_NUM_PRIOS 11
85#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS) 85#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
86/* Vlan, mac, ttc, aRFS */ 86/* Vlan, mac, ttc, inner ttc, aRFS */
87#define KERNEL_NIC_PRIO_NUM_LEVELS 4 87#define KERNEL_NIC_PRIO_NUM_LEVELS 5
88#define KERNEL_NIC_NUM_PRIOS 1 88#define KERNEL_NIC_NUM_PRIOS 1
89/* One more level for tc */ 89/* One more level for tc */
90#define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1) 90#define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1)