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
13struct mlx5_flow_attr;
14struct mlx5e_tc_mod_hdr_acts;
15struct mlx5_rep_uplink_priv;
16struct mlx5e_tc_flow;
17struct mlx5e_priv;
18
19struct mlx5_fs_chains;
20struct mlx5_tc_ct_priv;
21struct mlx5_ct_flow;
22
23struct nf_flowtable;
24
25struct mlx5_ct_attr {
26	u16 zone;
27	u16 ct_action;
28	struct nf_flowtable *nf_ft;
29	u32 ct_labels_id;
30	u32 act_miss_mapping;
31	u64 act_miss_cookie;
32	bool offloaded;
33	struct mlx5_ct_ft *ft;
34};
35
36#define zone_to_reg_ct {\
37	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
38	.moffset = 0,\
39	.mlen = 16,\
40	.soffset = MLX5_BYTE_OFF(fte_match_param,\
41				 misc_parameters_2.metadata_reg_c_2),\
42}
43
44#define ctstate_to_reg_ct {\
45	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
46	.moffset = 16,\
47	.mlen = 16,\
48	.soffset = MLX5_BYTE_OFF(fte_match_param,\
49				 misc_parameters_2.metadata_reg_c_2),\
50}
51
52#define mark_to_reg_ct {\
53	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_3,\
54	.moffset = 0,\
55	.mlen = 32,\
56	.soffset = MLX5_BYTE_OFF(fte_match_param,\
57				 misc_parameters_2.metadata_reg_c_3),\
58}
59
60#define labels_to_reg_ct {\
61	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_4,\
62	.moffset = 0,\
63	.mlen = 32,\
64	.soffset = MLX5_BYTE_OFF(fte_match_param,\
65				 misc_parameters_2.metadata_reg_c_4),\
66}
67
68/* 8 LSB of metadata C5 are reserved for packet color */
69#define fteid_to_reg_ct {\
70	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\
71	.moffset = 8,\
72	.mlen = 24,\
73	.soffset = MLX5_BYTE_OFF(fte_match_param,\
74				 misc_parameters_2.metadata_reg_c_5),\
75}
76
77#define zone_restore_to_reg_ct {\
78	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
79	.moffset = 0,\
80	.mlen = ESW_ZONE_ID_BITS,\
81	.soffset = MLX5_BYTE_OFF(fte_match_param,\
82				 misc_parameters_2.metadata_reg_c_1),\
83}
84
85#define nic_zone_restore_to_reg_ct {\
86	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B,\
87	.moffset = 16,\
88	.mlen = ESW_ZONE_ID_BITS,\
89}
90
91#define MLX5_CT_ZONE_BITS MLX5_REG_MAPPING_MBITS(ZONE_TO_REG)
92#define MLX5_CT_ZONE_MASK MLX5_REG_MAPPING_MASK(ZONE_TO_REG)
93
94#if IS_ENABLED(CONFIG_MLX5_TC_CT)
95
96struct mlx5_tc_ct_priv *
97mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
98		struct mod_hdr_tbl *mod_hdr,
99		enum mlx5_flow_namespace_type ns_type,
100		struct mlx5e_post_act *post_act);
101void
102mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv);
103
104void
105mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr);
106
107int
108mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
109		     struct mlx5_flow_spec *spec,
110		     struct flow_cls_offload *f,
111		     struct mlx5_ct_attr *ct_attr,
112		     struct netlink_ext_ack *extack);
113int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
114int
115mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
116			struct mlx5_flow_attr *attr,
117			const struct flow_action_entry *act,
118			struct netlink_ext_ack *extack);
119
120int
121mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr);
122
123void
124mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
125		       struct mlx5_flow_attr *attr);
126
127bool
128mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
129			 struct sk_buff *skb, u8 zone_restore_id);
130
131#else /* CONFIG_MLX5_TC_CT */
132
133static inline struct mlx5_tc_ct_priv *
134mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
135		struct mod_hdr_tbl *mod_hdr,
136		enum mlx5_flow_namespace_type ns_type,
137		struct mlx5e_post_act *post_act)
138{
139	return NULL;
140}
141
142static inline void
143mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
144{
145}
146
147static inline void
148mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {}
149
150static inline int
151mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
152		     struct mlx5_flow_spec *spec,
153		     struct flow_cls_offload *f,
154		     struct mlx5_ct_attr *ct_attr,
155		     struct netlink_ext_ack *extack)
156{
157	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
158
159	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
160		return 0;
161
162	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
163	return -EOPNOTSUPP;
164}
165
166static inline int
167mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
168{
169	return 0;
170}
171
172static inline int
173mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
174			struct mlx5_flow_attr *attr,
175			const struct flow_action_entry *act,
176			struct netlink_ext_ack *extack)
177{
178	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
179	return -EOPNOTSUPP;
180}
181
182static inline int
183mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
184			struct mlx5_flow_attr *attr)
185{
186	return -EOPNOTSUPP;
187}
188
189static inline void
190mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
191		       struct mlx5_flow_attr *attr)
192{
193}
194
195static inline bool
196mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
197			 struct sk_buff *skb, u8 zone_restore_id)
198{
199	if (!zone_restore_id)
200		return true;
201
202	return false;
203}
204
205#endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
206#endif /* __MLX5_EN_TC_CT_H__ */
207