1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2021 Mellanox Technologies. */
3
4 #ifndef __MLX5_EN_TC_PRIV_H__
5 #define __MLX5_EN_TC_PRIV_H__
6
7 #include "en_tc.h"
8
9 #define MLX5E_TC_FLOW_BASE (MLX5E_TC_FLAG_LAST_EXPORTED_BIT + 1)
10
11 #define MLX5E_TC_MAX_SPLITS 1
12
13 enum {
14 MLX5E_TC_FLOW_FLAG_INGRESS = MLX5E_TC_FLAG_INGRESS_BIT,
15 MLX5E_TC_FLOW_FLAG_EGRESS = MLX5E_TC_FLAG_EGRESS_BIT,
16 MLX5E_TC_FLOW_FLAG_ESWITCH = MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
17 MLX5E_TC_FLOW_FLAG_FT = MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
18 MLX5E_TC_FLOW_FLAG_NIC = MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
19 MLX5E_TC_FLOW_FLAG_OFFLOADED = MLX5E_TC_FLOW_BASE,
20 MLX5E_TC_FLOW_FLAG_HAIRPIN = MLX5E_TC_FLOW_BASE + 1,
21 MLX5E_TC_FLOW_FLAG_HAIRPIN_RSS = MLX5E_TC_FLOW_BASE + 2,
22 MLX5E_TC_FLOW_FLAG_SLOW = MLX5E_TC_FLOW_BASE + 3,
23 MLX5E_TC_FLOW_FLAG_DUP = MLX5E_TC_FLOW_BASE + 4,
24 MLX5E_TC_FLOW_FLAG_NOT_READY = MLX5E_TC_FLOW_BASE + 5,
25 MLX5E_TC_FLOW_FLAG_DELETED = MLX5E_TC_FLOW_BASE + 6,
26 MLX5E_TC_FLOW_FLAG_CT = MLX5E_TC_FLOW_BASE + 7,
27 MLX5E_TC_FLOW_FLAG_L3_TO_L2_DECAP = MLX5E_TC_FLOW_BASE + 8,
28 MLX5E_TC_FLOW_FLAG_TUN_RX = MLX5E_TC_FLOW_BASE + 9,
29 MLX5E_TC_FLOW_FLAG_FAILED = MLX5E_TC_FLOW_BASE + 10,
30 MLX5E_TC_FLOW_FLAG_SAMPLE = MLX5E_TC_FLOW_BASE + 11,
31 };
32
33 struct mlx5e_tc_flow_parse_attr {
34 const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS];
35 struct net_device *filter_dev;
36 struct mlx5_flow_spec spec;
37 struct mlx5e_tc_mod_hdr_acts mod_hdr_acts;
38 int mirred_ifindex[MLX5_MAX_FLOW_FWD_VPORTS];
39 struct ethhdr eth;
40 };
41
42 /* Helper struct for accessing a struct containing list_head array.
43 * Containing struct
44 * |- Helper array
45 * [0] Helper item 0
46 * |- list_head item 0
47 * |- index (0)
48 * [1] Helper item 1
49 * |- list_head item 1
50 * |- index (1)
51 * To access the containing struct from one of the list_head items:
52 * 1. Get the helper item from the list_head item using
53 * helper item =
54 * container_of(list_head item, helper struct type, list_head field)
55 * 2. Get the contining struct from the helper item and its index in the array:
56 * containing struct =
57 * container_of(helper item, containing struct type, helper field[index])
58 */
59 struct encap_flow_item {
60 struct mlx5e_encap_entry *e; /* attached encap instance */
61 struct list_head list;
62 int index;
63 };
64
65 struct encap_route_flow_item {
66 struct mlx5e_route_entry *r; /* attached route instance */
67 int index;
68 };
69
70 struct mlx5e_tc_flow {
71 struct rhash_head node;
72 struct mlx5e_priv *priv;
73 u64 cookie;
74 unsigned long flags;
75 struct mlx5_flow_handle *rule[MLX5E_TC_MAX_SPLITS + 1];
76
77 /* flows sharing the same reformat object - currently mpls decap */
78 struct list_head l3_to_l2_reformat;
79 struct mlx5e_decap_entry *decap_reformat;
80
81 /* flows sharing same route entry */
82 struct list_head decap_routes;
83 struct mlx5e_route_entry *decap_route;
84 struct encap_route_flow_item encap_routes[MLX5_MAX_FLOW_FWD_VPORTS];
85
86 /* Flow can be associated with multiple encap IDs.
87 * The number of encaps is bounded by the number of supported
88 * destinations.
89 */
90 struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
91 struct mlx5e_tc_flow *peer_flow;
92 struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
93 struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
94 struct list_head hairpin; /* flows sharing the same hairpin */
95 struct list_head peer; /* flows with peer flow */
96 struct list_head unready; /* flows not ready to be offloaded (e.g
97 * due to missing route)
98 */
99 struct net_device *orig_dev; /* netdev adding flow first */
100 int tmp_entry_index;
101 struct list_head tmp_list; /* temporary flow list used by neigh update */
102 refcount_t refcnt;
103 struct rcu_head rcu_head;
104 struct completion init_done;
105 struct completion del_hw_done;
106 int tunnel_id; /* the mapped tunnel id of this flow */
107 struct mlx5_flow_attr *attr;
108 };
109
110 u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer);
111
112 struct mlx5_flow_handle *
113 mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
114 struct mlx5e_tc_flow *flow,
115 struct mlx5_flow_spec *spec,
116 struct mlx5_flow_attr *attr);
117
118 bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow);
119
__flow_flag_set(struct mlx5e_tc_flow * flow,unsigned long flag)120 static inline void __flow_flag_set(struct mlx5e_tc_flow *flow, unsigned long flag)
121 {
122 /* Complete all memory stores before setting bit. */
123 smp_mb__before_atomic();
124 set_bit(flag, &flow->flags);
125 }
126
127 #define flow_flag_set(flow, flag) __flow_flag_set(flow, MLX5E_TC_FLOW_FLAG_##flag)
128
__flow_flag_test_and_set(struct mlx5e_tc_flow * flow,unsigned long flag)129 static inline bool __flow_flag_test_and_set(struct mlx5e_tc_flow *flow,
130 unsigned long flag)
131 {
132 /* test_and_set_bit() provides all necessary barriers */
133 return test_and_set_bit(flag, &flow->flags);
134 }
135
136 #define flow_flag_test_and_set(flow, flag) \
137 __flow_flag_test_and_set(flow, \
138 MLX5E_TC_FLOW_FLAG_##flag)
139
__flow_flag_clear(struct mlx5e_tc_flow * flow,unsigned long flag)140 static inline void __flow_flag_clear(struct mlx5e_tc_flow *flow, unsigned long flag)
141 {
142 /* Complete all memory stores before clearing bit. */
143 smp_mb__before_atomic();
144 clear_bit(flag, &flow->flags);
145 }
146
147 #define flow_flag_clear(flow, flag) __flow_flag_clear(flow, \
148 MLX5E_TC_FLOW_FLAG_##flag)
149
__flow_flag_test(struct mlx5e_tc_flow * flow,unsigned long flag)150 static inline bool __flow_flag_test(struct mlx5e_tc_flow *flow, unsigned long flag)
151 {
152 bool ret = test_bit(flag, &flow->flags);
153
154 /* Read fields of flow structure only after checking flags. */
155 smp_mb__after_atomic();
156 return ret;
157 }
158
159 #define flow_flag_test(flow, flag) __flow_flag_test(flow, \
160 MLX5E_TC_FLOW_FLAG_##flag)
161
162 void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
163 struct mlx5e_tc_flow *flow);
164 struct mlx5_flow_handle *
165 mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
166 struct mlx5e_tc_flow *flow,
167 struct mlx5_flow_spec *spec);
168 void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
169 struct mlx5e_tc_flow *flow,
170 struct mlx5_flow_attr *attr);
171
172 struct mlx5e_tc_flow *mlx5e_flow_get(struct mlx5e_tc_flow *flow);
173 void mlx5e_flow_put(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow);
174
175 struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow);
176
177 #endif /* __MLX5_EN_TC_PRIV_H__ */
178