Merge branch 'next' into for-linus
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / en / tc_ct.h
1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2018 Mellanox Technologies. */
3
4 #ifndef __MLX5_EN_TC_CT_H__
5 #define __MLX5_EN_TC_CT_H__
6
7 #include <net/pkt_cls.h>
8 #include <linux/mlx5/fs.h>
9 #include <net/tc_act/tc_ct.h>
10
11 #include "en.h"
12
13 struct mlx5_esw_flow_attr;
14 struct mlx5e_tc_mod_hdr_acts;
15 struct mlx5_rep_uplink_priv;
16 struct mlx5e_tc_flow;
17 struct mlx5e_priv;
18
19 struct mlx5_ct_flow;
20
21 struct nf_flowtable;
22
23 struct mlx5_ct_attr {
24         u16 zone;
25         u16 ct_action;
26         struct mlx5_ct_flow *ct_flow;
27         struct nf_flowtable *nf_ft;
28         u32 ct_labels_id;
29 };
30
31 #define zone_to_reg_ct {\
32         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
33         .moffset = 0,\
34         .mlen = 2,\
35         .soffset = MLX5_BYTE_OFF(fte_match_param,\
36                                  misc_parameters_2.metadata_reg_c_2) + 2,\
37 }
38
39 #define ctstate_to_reg_ct {\
40         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
41         .moffset = 2,\
42         .mlen = 2,\
43         .soffset = MLX5_BYTE_OFF(fte_match_param,\
44                                  misc_parameters_2.metadata_reg_c_2),\
45 }
46
47 #define mark_to_reg_ct {\
48         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_3,\
49         .moffset = 0,\
50         .mlen = 4,\
51         .soffset = MLX5_BYTE_OFF(fte_match_param,\
52                                  misc_parameters_2.metadata_reg_c_3),\
53 }
54
55 #define labels_to_reg_ct {\
56         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_4,\
57         .moffset = 0,\
58         .mlen = 4,\
59         .soffset = MLX5_BYTE_OFF(fte_match_param,\
60                                  misc_parameters_2.metadata_reg_c_4),\
61 }
62
63 #define fteid_to_reg_ct {\
64         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\
65         .moffset = 0,\
66         .mlen = 4,\
67         .soffset = MLX5_BYTE_OFF(fte_match_param,\
68                                  misc_parameters_2.metadata_reg_c_5),\
69 }
70
71 #define zone_restore_to_reg_ct {\
72         .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
73         .moffset = 0,\
74         .mlen = 1,\
75         .soffset = MLX5_BYTE_OFF(fte_match_param,\
76                                  misc_parameters_2.metadata_reg_c_1) + 3,\
77 }
78
79 #define REG_MAPPING_MLEN(reg) (mlx5e_tc_attr_to_reg_mappings[reg].mlen)
80 #define ZONE_RESTORE_BITS (REG_MAPPING_MLEN(ZONE_RESTORE_TO_REG) * 8)
81 #define ZONE_RESTORE_MAX GENMASK(ZONE_RESTORE_BITS - 1, 0)
82
83 #if IS_ENABLED(CONFIG_MLX5_TC_CT)
84
85 int
86 mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv);
87 void
88 mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv);
89
90 void
91 mlx5_tc_ct_match_del(struct mlx5e_priv *priv, struct mlx5_ct_attr *ct_attr);
92
93 int
94 mlx5_tc_ct_match_add(struct mlx5e_priv *priv,
95                      struct mlx5_flow_spec *spec,
96                      struct flow_cls_offload *f,
97                      struct mlx5_ct_attr *ct_attr,
98                      struct netlink_ext_ack *extack);
99 int
100 mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
101                             struct mlx5_flow_spec *spec);
102 int
103 mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
104                         struct mlx5_esw_flow_attr *attr,
105                         const struct flow_action_entry *act,
106                         struct netlink_ext_ack *extack);
107
108 struct mlx5_flow_handle *
109 mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
110                         struct mlx5e_tc_flow *flow,
111                         struct mlx5_flow_spec *spec,
112                         struct mlx5_esw_flow_attr *attr,
113                         struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
114 void
115 mlx5_tc_ct_delete_flow(struct mlx5e_priv *priv,
116                        struct mlx5e_tc_flow *flow,
117                        struct mlx5_esw_flow_attr *attr);
118
119 bool
120 mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
121                          struct sk_buff *skb, u8 zone_restore_id);
122
123 #else /* CONFIG_MLX5_TC_CT */
124
125 static inline int
126 mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
127 {
128         return 0;
129 }
130
131 static inline void
132 mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv)
133 {
134 }
135
136 static inline void
137 mlx5_tc_ct_match_del(struct mlx5e_priv *priv, struct mlx5_ct_attr *ct_attr) {}
138
139 static inline int
140 mlx5_tc_ct_match_add(struct mlx5e_priv *priv,
141                      struct mlx5_flow_spec *spec,
142                      struct flow_cls_offload *f,
143                      struct mlx5_ct_attr *ct_attr,
144                      struct netlink_ext_ack *extack)
145 {
146         struct flow_rule *rule = flow_cls_offload_flow_rule(f);
147
148         if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
149                 return 0;
150
151         NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
152         netdev_warn(priv->netdev, "mlx5 tc ct offload isn't enabled.\n");
153         return -EOPNOTSUPP;
154 }
155
156 static inline int
157 mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
158                             struct mlx5_flow_spec *spec)
159 {
160         return 0;
161 }
162
163 static inline int
164 mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
165                         struct mlx5_esw_flow_attr *attr,
166                         const struct flow_action_entry *act,
167                         struct netlink_ext_ack *extack)
168 {
169         NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
170         netdev_warn(priv->netdev, "mlx5 tc ct offload isn't enabled.\n");
171         return -EOPNOTSUPP;
172 }
173
174 static inline struct mlx5_flow_handle *
175 mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
176                         struct mlx5e_tc_flow *flow,
177                         struct mlx5_flow_spec *spec,
178                         struct mlx5_esw_flow_attr *attr,
179                         struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
180 {
181         return ERR_PTR(-EOPNOTSUPP);
182 }
183
184 static inline void
185 mlx5_tc_ct_delete_flow(struct mlx5e_priv *priv,
186                        struct mlx5e_tc_flow *flow,
187                        struct mlx5_esw_flow_attr *attr)
188 {
189 }
190
191 static inline bool
192 mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
193                          struct sk_buff *skb, u8 zone_restore_id)
194 {
195         if (!zone_restore_id)
196                 return true;
197
198         return false;
199 }
200
201 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
202 #endif /* __MLX5_EN_TC_CT_H__ */