aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.c281
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c108
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c4
-rw-r--r--include/linux/mlx5/mlx5_ifc.h2
6 files changed, 384 insertions, 40 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 eecbc6d4f51f..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,28 @@ 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
683static u8 mlx5e_etype_to_ipv(u16 ethertype)
684{
685 if (ethertype == ETH_P_IP)
686 return 4;
687
688 if (ethertype == ETH_P_IPV6)
689 return 6;
690
691 return 0;
692}
693
663static struct mlx5_flow_handle * 694static struct mlx5_flow_handle *
664mlx5e_generate_ttc_rule(struct mlx5e_priv *priv, 695mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
665 struct mlx5_flow_table *ft, 696 struct mlx5_flow_table *ft,
@@ -667,10 +698,12 @@ mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
667 u16 etype, 698 u16 etype,
668 u8 proto) 699 u8 proto)
669{ 700{
701 int match_ipv_outer = MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version);
670 MLX5_DECLARE_FLOW_ACT(flow_act); 702 MLX5_DECLARE_FLOW_ACT(flow_act);
671 struct mlx5_flow_handle *rule; 703 struct mlx5_flow_handle *rule;
672 struct mlx5_flow_spec *spec; 704 struct mlx5_flow_spec *spec;
673 int err = 0; 705 int err = 0;
706 u8 ipv;
674 707
675 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 708 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
676 if (!spec) 709 if (!spec)
@@ -681,7 +714,13 @@ mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
681 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol); 714 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
682 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, proto); 715 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, proto);
683 } 716 }
684 if (etype) { 717
718 ipv = mlx5e_etype_to_ipv(etype);
719 if (match_ipv_outer && ipv) {
720 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
721 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
722 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, ipv);
723 } else if (etype) {
685 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 724 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
686 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype); 725 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
687 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype); 726 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype);
@@ -723,6 +762,20 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv)
723 goto del_rules; 762 goto del_rules;
724 } 763 }
725 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
726 return 0; 779 return 0;
727 780
728del_rules: 781del_rules:
@@ -733,13 +786,23 @@ del_rules:
733} 786}
734 787
735#define MLX5E_TTC_NUM_GROUPS 3 788#define MLX5E_TTC_NUM_GROUPS 3
736#define MLX5E_TTC_GROUP1_SIZE BIT(3) 789#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT)
737#define MLX5E_TTC_GROUP2_SIZE BIT(1) 790#define MLX5E_TTC_GROUP2_SIZE BIT(1)
738#define MLX5E_TTC_GROUP3_SIZE BIT(0) 791#define MLX5E_TTC_GROUP3_SIZE BIT(0)
739#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ 792#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\
740 MLX5E_TTC_GROUP2_SIZE +\ 793 MLX5E_TTC_GROUP2_SIZE +\
741 MLX5E_TTC_GROUP3_SIZE) 794 MLX5E_TTC_GROUP3_SIZE)
742static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc) 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
804static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc,
805 bool use_ipv)
743{ 806{
744 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 807 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
745 struct mlx5e_flow_table *ft = &ttc->ft; 808 struct mlx5e_flow_table *ft = &ttc->ft;
@@ -761,7 +824,10 @@ static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc)
761 /* L4 Group */ 824 /* L4 Group */
762 mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 825 mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
763 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 826 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol);
764 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 827 if (use_ipv)
828 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_version);
829 else
830 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype);
765 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 831 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
766 MLX5_SET_CFG(in, start_flow_index, ix); 832 MLX5_SET_CFG(in, start_flow_index, ix);
767 ix += MLX5E_TTC_GROUP1_SIZE; 833 ix += MLX5E_TTC_GROUP1_SIZE;
@@ -802,6 +868,190 @@ err:
802 return err; 868 return err;
803} 869}
804 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
805void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv) 1055void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
806{ 1056{
807 struct mlx5e_ttc_table *ttc = &priv->fs.ttc; 1057 struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
@@ -812,6 +1062,7 @@ void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
812 1062
813int mlx5e_create_ttc_table(struct mlx5e_priv *priv) 1063int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
814{ 1064{
1065 bool match_ipv_outer = MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version);
815 struct mlx5e_ttc_table *ttc = &priv->fs.ttc; 1066 struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
816 struct mlx5_flow_table_attr ft_attr = {}; 1067 struct mlx5_flow_table_attr ft_attr = {};
817 struct mlx5e_flow_table *ft = &ttc->ft; 1068 struct mlx5e_flow_table *ft = &ttc->ft;
@@ -828,7 +1079,7 @@ int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
828 return err; 1079 return err;
829 } 1080 }
830 1081
831 err = mlx5e_create_ttc_table_groups(ttc); 1082 err = mlx5e_create_ttc_table_groups(ttc, match_ipv_outer);
832 if (err) 1083 if (err)
833 goto err; 1084 goto err;
834 1085
@@ -1154,11 +1405,18 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
1154 priv->netdev->hw_features &= ~NETIF_F_NTUPLE; 1405 priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
1155 } 1406 }
1156 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
1157 err = mlx5e_create_ttc_table(priv); 1415 err = mlx5e_create_ttc_table(priv);
1158 if (err) { 1416 if (err) {
1159 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",
1160 err); 1418 err);
1161 goto err_destroy_arfs_tables; 1419 goto err_destroy_inner_ttc_table;
1162 } 1420 }
1163 1421
1164 err = mlx5e_create_l2_table(priv); 1422 err = mlx5e_create_l2_table(priv);
@@ -1183,6 +1441,8 @@ err_destroy_l2_table:
1183 mlx5e_destroy_l2_table(priv); 1441 mlx5e_destroy_l2_table(priv);
1184err_destroy_ttc_table: 1442err_destroy_ttc_table:
1185 mlx5e_destroy_ttc_table(priv); 1443 mlx5e_destroy_ttc_table(priv);
1444err_destroy_inner_ttc_table:
1445 mlx5e_destroy_inner_ttc_table(priv);
1186err_destroy_arfs_tables: 1446err_destroy_arfs_tables:
1187 mlx5e_arfs_destroy_tables(priv); 1447 mlx5e_arfs_destroy_tables(priv);
1188 1448
@@ -1194,6 +1454,7 @@ void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv)
1194 mlx5e_destroy_vlan_table(priv); 1454 mlx5e_destroy_vlan_table(priv);
1195 mlx5e_destroy_l2_table(priv); 1455 mlx5e_destroy_l2_table(priv);
1196 mlx5e_destroy_ttc_table(priv); 1456 mlx5e_destroy_ttc_table(priv);
1457 mlx5e_destroy_inner_ttc_table(priv);
1197 mlx5e_arfs_destroy_tables(priv); 1458 mlx5e_arfs_destroy_tables(priv);
1198 mlx5e_ethtool_cleanup_steering(priv); 1459 mlx5e_ethtool_cleanup_steering(priv);
1199} 1460}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index fdc2b92f020b..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)
@@ -3499,13 +3542,13 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev,
3499 mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 0); 3542 mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 0);
3500} 3543}
3501 3544
3502static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, 3545static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
3503 struct sk_buff *skb, 3546 struct sk_buff *skb,
3504 netdev_features_t features) 3547 netdev_features_t features)
3505{ 3548{
3506 struct udphdr *udph; 3549 struct udphdr *udph;
3507 u16 proto; 3550 u8 proto;
3508 u16 port = 0; 3551 u16 port;
3509 3552
3510 switch (vlan_get_protocol(skb)) { 3553 switch (vlan_get_protocol(skb)) {
3511 case htons(ETH_P_IP): 3554 case htons(ETH_P_IP):
@@ -3518,14 +3561,17 @@ static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv,
3518 goto out; 3561 goto out;
3519 } 3562 }
3520 3563
3521 if (proto == IPPROTO_UDP) { 3564 switch (proto) {
3565 case IPPROTO_GRE:
3566 return features;
3567 case IPPROTO_UDP:
3522 udph = udp_hdr(skb); 3568 udph = udp_hdr(skb);
3523 port = be16_to_cpu(udph->dest); 3569 port = be16_to_cpu(udph->dest);
3524 }
3525 3570
3526 /* Verify if UDP port is being offloaded by HW */ 3571 /* Verify if UDP port is being offloaded by HW */
3527 if (port && mlx5e_vxlan_lookup_port(priv, port)) 3572 if (mlx5e_vxlan_lookup_port(priv, port))
3528 return features; 3573 return features;
3574 }
3529 3575
3530out: 3576out:
3531 /* Disable CSUM and GSO if the udp dport is not offloaded by HW */ 3577 /* Disable CSUM and GSO if the udp dport is not offloaded by HW */
@@ -3549,7 +3595,7 @@ static netdev_features_t mlx5e_features_check(struct sk_buff *skb,
3549 /* Validate if the tunneled packet is being offloaded by HW */ 3595 /* Validate if the tunneled packet is being offloaded by HW */
3550 if (skb->encapsulation && 3596 if (skb->encapsulation &&
3551 (features & NETIF_F_CSUM_MASK || features & NETIF_F_GSO_MASK)) 3597 (features & NETIF_F_CSUM_MASK || features & NETIF_F_GSO_MASK))
3552 return mlx5e_vxlan_features_check(priv, skb, features); 3598 return mlx5e_tunnel_features_check(priv, skb, features);
3553 3599
3554 return features; 3600 return features;
3555} 3601}
@@ -4014,20 +4060,32 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
4014 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX; 4060 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
4015 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; 4061 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
4016 4062
4017 if (mlx5e_vxlan_allowed(mdev)) { 4063 if (mlx5e_vxlan_allowed(mdev) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
4018 netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | 4064 netdev->hw_features |= NETIF_F_GSO_PARTIAL;
4019 NETIF_F_GSO_UDP_TUNNEL_CSUM |
4020 NETIF_F_GSO_PARTIAL;
4021 netdev->hw_enc_features |= NETIF_F_IP_CSUM; 4065 netdev->hw_enc_features |= NETIF_F_IP_CSUM;
4022 netdev->hw_enc_features |= NETIF_F_IPV6_CSUM; 4066 netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
4023 netdev->hw_enc_features |= NETIF_F_TSO; 4067 netdev->hw_enc_features |= NETIF_F_TSO;
4024 netdev->hw_enc_features |= NETIF_F_TSO6; 4068 netdev->hw_enc_features |= NETIF_F_TSO6;
4025 netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; 4069 netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
4026 netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM | 4070 }
4027 NETIF_F_GSO_PARTIAL; 4071
4072 if (mlx5e_vxlan_allowed(mdev)) {
4073 netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
4074 NETIF_F_GSO_UDP_TUNNEL_CSUM;
4075 netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
4076 NETIF_F_GSO_UDP_TUNNEL_CSUM;
4028 netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; 4077 netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
4029 } 4078 }
4030 4079
4080 if (MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
4081 netdev->hw_features |= NETIF_F_GSO_GRE |
4082 NETIF_F_GSO_GRE_CSUM;
4083 netdev->hw_enc_features |= NETIF_F_GSO_GRE |
4084 NETIF_F_GSO_GRE_CSUM;
4085 netdev->gso_partial_features |= NETIF_F_GSO_GRE |
4086 NETIF_F_GSO_GRE_CSUM;
4087 }
4088
4031 mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled); 4089 mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled);
4032 4090
4033 if (fcs_supported) 4091 if (fcs_supported)
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)
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index ae7d09b9c52f..3d5d32e5446c 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -602,7 +602,7 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
602 u8 reserved_at_1a[0x1]; 602 u8 reserved_at_1a[0x1];
603 u8 tunnel_lso_const_out_ip_id[0x1]; 603 u8 tunnel_lso_const_out_ip_id[0x1];
604 u8 reserved_at_1c[0x2]; 604 u8 reserved_at_1c[0x2];
605 u8 tunnel_statless_gre[0x1]; 605 u8 tunnel_stateless_gre[0x1];
606 u8 tunnel_stateless_vxlan[0x1]; 606 u8 tunnel_stateless_vxlan[0x1];
607 607
608 u8 swp[0x1]; 608 u8 swp[0x1];