.. | .. |
---|
35 | 35 | #include <linux/ipv6.h> |
---|
36 | 36 | #include <linux/tcp.h> |
---|
37 | 37 | #include <linux/mlx5/fs.h> |
---|
| 38 | +#include <linux/mlx5/mpfs.h> |
---|
38 | 39 | #include "en.h" |
---|
39 | 40 | #include "lib/mpfs.h" |
---|
40 | 41 | |
---|
.. | .. |
---|
678 | 679 | int i; |
---|
679 | 680 | |
---|
680 | 681 | for (i = 0; i < MLX5E_NUM_TT; i++) { |
---|
681 | | - if (!IS_ERR_OR_NULL(ttc->rules[i])) { |
---|
682 | | - mlx5_del_flow_rules(ttc->rules[i]); |
---|
683 | | - ttc->rules[i] = NULL; |
---|
| 682 | + if (!IS_ERR_OR_NULL(ttc->rules[i].rule)) { |
---|
| 683 | + mlx5_del_flow_rules(ttc->rules[i].rule); |
---|
| 684 | + ttc->rules[i].rule = NULL; |
---|
684 | 685 | } |
---|
685 | 686 | } |
---|
686 | 687 | |
---|
.. | .. |
---|
753 | 754 | .etype = ETH_P_IPV6, |
---|
754 | 755 | .proto = IPPROTO_GRE, |
---|
755 | 756 | }, |
---|
| 757 | + [MLX5E_TT_IPV4_IPIP] = { |
---|
| 758 | + .etype = ETH_P_IP, |
---|
| 759 | + .proto = IPPROTO_IPIP, |
---|
| 760 | + }, |
---|
| 761 | + [MLX5E_TT_IPV6_IPIP] = { |
---|
| 762 | + .etype = ETH_P_IPV6, |
---|
| 763 | + .proto = IPPROTO_IPIP, |
---|
| 764 | + }, |
---|
| 765 | + [MLX5E_TT_IPV4_IPV6] = { |
---|
| 766 | + .etype = ETH_P_IP, |
---|
| 767 | + .proto = IPPROTO_IPV6, |
---|
| 768 | + }, |
---|
| 769 | + [MLX5E_TT_IPV6_IPV6] = { |
---|
| 770 | + .etype = ETH_P_IPV6, |
---|
| 771 | + .proto = IPPROTO_IPV6, |
---|
| 772 | + }, |
---|
| 773 | + |
---|
756 | 774 | }; |
---|
| 775 | + |
---|
| 776 | +bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type) |
---|
| 777 | +{ |
---|
| 778 | + switch (proto_type) { |
---|
| 779 | + case IPPROTO_GRE: |
---|
| 780 | + return MLX5_CAP_ETH(mdev, tunnel_stateless_gre); |
---|
| 781 | + case IPPROTO_IPIP: |
---|
| 782 | + case IPPROTO_IPV6: |
---|
| 783 | + return MLX5_CAP_ETH(mdev, tunnel_stateless_ip_over_ip); |
---|
| 784 | + default: |
---|
| 785 | + return false; |
---|
| 786 | + } |
---|
| 787 | +} |
---|
| 788 | + |
---|
| 789 | +bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev) |
---|
| 790 | +{ |
---|
| 791 | + int tt; |
---|
| 792 | + |
---|
| 793 | + for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) { |
---|
| 794 | + if (mlx5e_tunnel_proto_supported(mdev, ttc_tunnel_rules[tt].proto)) |
---|
| 795 | + return true; |
---|
| 796 | + } |
---|
| 797 | + return false; |
---|
| 798 | +} |
---|
| 799 | + |
---|
| 800 | +bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) |
---|
| 801 | +{ |
---|
| 802 | + return (mlx5e_any_tunnel_proto_supported(mdev) && |
---|
| 803 | + MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version)); |
---|
| 804 | +} |
---|
757 | 805 | |
---|
758 | 806 | static u8 mlx5e_etype_to_ipv(u16 ethertype) |
---|
759 | 807 | { |
---|
.. | .. |
---|
816 | 864 | struct mlx5e_ttc_table *ttc) |
---|
817 | 865 | { |
---|
818 | 866 | struct mlx5_flow_destination dest = {}; |
---|
819 | | - struct mlx5_flow_handle **rules; |
---|
| 867 | + struct mlx5_flow_handle **trules; |
---|
| 868 | + struct mlx5e_ttc_rule *rules; |
---|
820 | 869 | struct mlx5_flow_table *ft; |
---|
821 | 870 | int tt; |
---|
822 | 871 | int err; |
---|
.. | .. |
---|
826 | 875 | |
---|
827 | 876 | dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; |
---|
828 | 877 | for (tt = 0; tt < MLX5E_NUM_TT; tt++) { |
---|
| 878 | + struct mlx5e_ttc_rule *rule = &rules[tt]; |
---|
| 879 | + |
---|
829 | 880 | if (tt == MLX5E_TT_ANY) |
---|
830 | 881 | dest.tir_num = params->any_tt_tirn; |
---|
831 | 882 | else |
---|
832 | 883 | dest.tir_num = params->indir_tirn[tt]; |
---|
833 | | - rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest, |
---|
834 | | - ttc_rules[tt].etype, |
---|
835 | | - ttc_rules[tt].proto); |
---|
836 | | - if (IS_ERR(rules[tt])) |
---|
| 884 | + |
---|
| 885 | + rule->rule = mlx5e_generate_ttc_rule(priv, ft, &dest, |
---|
| 886 | + ttc_rules[tt].etype, |
---|
| 887 | + ttc_rules[tt].proto); |
---|
| 888 | + if (IS_ERR(rule->rule)) { |
---|
| 889 | + err = PTR_ERR(rule->rule); |
---|
| 890 | + rule->rule = NULL; |
---|
837 | 891 | goto del_rules; |
---|
| 892 | + } |
---|
| 893 | + rule->default_dest = dest; |
---|
838 | 894 | } |
---|
839 | 895 | |
---|
840 | 896 | if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev)) |
---|
841 | 897 | return 0; |
---|
842 | 898 | |
---|
843 | | - rules = ttc->tunnel_rules; |
---|
| 899 | + trules = ttc->tunnel_rules; |
---|
844 | 900 | dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; |
---|
845 | 901 | dest.ft = params->inner_ttc->ft.t; |
---|
846 | 902 | for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) { |
---|
847 | | - rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest, |
---|
848 | | - ttc_tunnel_rules[tt].etype, |
---|
849 | | - ttc_tunnel_rules[tt].proto); |
---|
850 | | - if (IS_ERR(rules[tt])) |
---|
| 903 | + if (!mlx5e_tunnel_proto_supported(priv->mdev, |
---|
| 904 | + ttc_tunnel_rules[tt].proto)) |
---|
| 905 | + continue; |
---|
| 906 | + trules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest, |
---|
| 907 | + ttc_tunnel_rules[tt].etype, |
---|
| 908 | + ttc_tunnel_rules[tt].proto); |
---|
| 909 | + if (IS_ERR(trules[tt])) { |
---|
| 910 | + err = PTR_ERR(trules[tt]); |
---|
| 911 | + trules[tt] = NULL; |
---|
851 | 912 | goto del_rules; |
---|
| 913 | + } |
---|
852 | 914 | } |
---|
853 | 915 | |
---|
854 | 916 | return 0; |
---|
855 | 917 | |
---|
856 | 918 | del_rules: |
---|
857 | | - err = PTR_ERR(rules[tt]); |
---|
858 | | - rules[tt] = NULL; |
---|
859 | 919 | mlx5e_cleanup_ttc_rules(ttc); |
---|
860 | 920 | return err; |
---|
861 | 921 | } |
---|
862 | | - |
---|
863 | | -#define MLX5E_TTC_NUM_GROUPS 3 |
---|
864 | | -#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT) |
---|
865 | | -#define MLX5E_TTC_GROUP2_SIZE BIT(1) |
---|
866 | | -#define MLX5E_TTC_GROUP3_SIZE BIT(0) |
---|
867 | | -#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ |
---|
868 | | - MLX5E_TTC_GROUP2_SIZE +\ |
---|
869 | | - MLX5E_TTC_GROUP3_SIZE) |
---|
870 | | - |
---|
871 | | -#define MLX5E_INNER_TTC_NUM_GROUPS 3 |
---|
872 | | -#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3) |
---|
873 | | -#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1) |
---|
874 | | -#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0) |
---|
875 | | -#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\ |
---|
876 | | - MLX5E_INNER_TTC_GROUP2_SIZE +\ |
---|
877 | | - MLX5E_INNER_TTC_GROUP3_SIZE) |
---|
878 | 922 | |
---|
879 | 923 | static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, |
---|
880 | 924 | bool use_ipv) |
---|
.. | .. |
---|
988 | 1032 | struct mlx5e_ttc_table *ttc) |
---|
989 | 1033 | { |
---|
990 | 1034 | struct mlx5_flow_destination dest = {}; |
---|
991 | | - struct mlx5_flow_handle **rules; |
---|
| 1035 | + struct mlx5e_ttc_rule *rules; |
---|
992 | 1036 | struct mlx5_flow_table *ft; |
---|
993 | 1037 | int err; |
---|
994 | 1038 | int tt; |
---|
995 | 1039 | |
---|
996 | 1040 | ft = ttc->ft.t; |
---|
997 | 1041 | rules = ttc->rules; |
---|
998 | | - |
---|
999 | 1042 | dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; |
---|
| 1043 | + |
---|
1000 | 1044 | for (tt = 0; tt < MLX5E_NUM_TT; tt++) { |
---|
| 1045 | + struct mlx5e_ttc_rule *rule = &rules[tt]; |
---|
| 1046 | + |
---|
1001 | 1047 | if (tt == MLX5E_TT_ANY) |
---|
1002 | 1048 | dest.tir_num = params->any_tt_tirn; |
---|
1003 | 1049 | else |
---|
1004 | 1050 | dest.tir_num = params->indir_tirn[tt]; |
---|
1005 | 1051 | |
---|
1006 | | - rules[tt] = mlx5e_generate_inner_ttc_rule(priv, ft, &dest, |
---|
1007 | | - ttc_rules[tt].etype, |
---|
1008 | | - ttc_rules[tt].proto); |
---|
1009 | | - if (IS_ERR(rules[tt])) |
---|
| 1052 | + rule->rule = mlx5e_generate_inner_ttc_rule(priv, ft, &dest, |
---|
| 1053 | + ttc_rules[tt].etype, |
---|
| 1054 | + ttc_rules[tt].proto); |
---|
| 1055 | + if (IS_ERR(rule->rule)) { |
---|
| 1056 | + err = PTR_ERR(rule->rule); |
---|
| 1057 | + rule->rule = NULL; |
---|
1010 | 1058 | goto del_rules; |
---|
| 1059 | + } |
---|
| 1060 | + rule->default_dest = dest; |
---|
1011 | 1061 | } |
---|
1012 | 1062 | |
---|
1013 | 1063 | return 0; |
---|
1014 | 1064 | |
---|
1015 | 1065 | del_rules: |
---|
1016 | | - err = PTR_ERR(rules[tt]); |
---|
1017 | | - rules[tt] = NULL; |
---|
| 1066 | + |
---|
1018 | 1067 | mlx5e_cleanup_ttc_rules(ttc); |
---|
1019 | 1068 | return err; |
---|
1020 | 1069 | } |
---|
.. | .. |
---|
1089 | 1138 | ttc_params->inner_ttc = &priv->fs.inner_ttc; |
---|
1090 | 1139 | } |
---|
1091 | 1140 | |
---|
1092 | | -void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) |
---|
| 1141 | +static void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) |
---|
1093 | 1142 | { |
---|
1094 | 1143 | struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; |
---|
1095 | 1144 | |
---|
.. | .. |
---|
1108 | 1157 | ft_attr->prio = MLX5E_NIC_PRIO; |
---|
1109 | 1158 | } |
---|
1110 | 1159 | |
---|
1111 | | -int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, |
---|
1112 | | - struct mlx5e_ttc_table *ttc) |
---|
| 1160 | +static int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, |
---|
| 1161 | + struct mlx5e_ttc_table *ttc) |
---|
1113 | 1162 | { |
---|
1114 | 1163 | struct mlx5e_flow_table *ft = &ttc->ft; |
---|
1115 | 1164 | int err; |
---|
.. | .. |
---|
1139 | 1188 | return err; |
---|
1140 | 1189 | } |
---|
1141 | 1190 | |
---|
1142 | | -void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, |
---|
1143 | | - struct mlx5e_ttc_table *ttc) |
---|
| 1191 | +static void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, |
---|
| 1192 | + struct mlx5e_ttc_table *ttc) |
---|
1144 | 1193 | { |
---|
1145 | 1194 | if (!mlx5e_tunnel_inner_ft_supported(priv->mdev)) |
---|
1146 | 1195 | return; |
---|
.. | .. |
---|
1184 | 1233 | return err; |
---|
1185 | 1234 | } |
---|
1186 | 1235 | |
---|
| 1236 | +int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type, |
---|
| 1237 | + struct mlx5_flow_destination *new_dest) |
---|
| 1238 | +{ |
---|
| 1239 | + return mlx5_modify_rule_destination(priv->fs.ttc.rules[type].rule, new_dest, NULL); |
---|
| 1240 | +} |
---|
| 1241 | + |
---|
| 1242 | +struct mlx5_flow_destination |
---|
| 1243 | +mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type) |
---|
| 1244 | +{ |
---|
| 1245 | + struct mlx5_flow_destination *dest = &priv->fs.ttc.rules[type].default_dest; |
---|
| 1246 | + |
---|
| 1247 | + WARN_ONCE(dest->type != MLX5_FLOW_DESTINATION_TYPE_TIR, |
---|
| 1248 | + "TTC[%d] default dest is not setup yet", type); |
---|
| 1249 | + |
---|
| 1250 | + return *dest; |
---|
| 1251 | +} |
---|
| 1252 | + |
---|
| 1253 | +int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type) |
---|
| 1254 | +{ |
---|
| 1255 | + struct mlx5_flow_destination dest = mlx5e_ttc_get_default_dest(priv, type); |
---|
| 1256 | + |
---|
| 1257 | + return mlx5e_ttc_fwd_dest(priv, type, &dest); |
---|
| 1258 | +} |
---|
| 1259 | + |
---|
1187 | 1260 | static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv, |
---|
1188 | 1261 | struct mlx5e_l2_rule *ai) |
---|
1189 | 1262 | { |
---|