.. | .. |
---|
35 | 35 | |
---|
36 | 36 | #include <linux/if_ether.h> |
---|
37 | 37 | #include <linux/if_link.h> |
---|
| 38 | +#include <linux/atomic.h> |
---|
38 | 39 | #include <net/devlink.h> |
---|
39 | 40 | #include <linux/mlx5/device.h> |
---|
40 | 41 | #include <linux/mlx5/eswitch.h> |
---|
| 42 | +#include <linux/mlx5/vport.h> |
---|
41 | 43 | #include <linux/mlx5/fs.h> |
---|
42 | 44 | #include "lib/mpfs.h" |
---|
| 45 | +#include "lib/fs_chains.h" |
---|
| 46 | +#include "en/tc_ct.h" |
---|
43 | 47 | |
---|
44 | 48 | #ifdef CONFIG_MLX5_ESWITCH |
---|
| 49 | + |
---|
| 50 | +#define ESW_OFFLOADS_DEFAULT_NUM_GROUPS 15 |
---|
45 | 51 | |
---|
46 | 52 | #define MLX5_MAX_UC_PER_VPORT(dev) \ |
---|
47 | 53 | (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list)) |
---|
48 | 54 | |
---|
49 | 55 | #define MLX5_MAX_MC_PER_VPORT(dev) \ |
---|
50 | 56 | (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list)) |
---|
51 | | - |
---|
52 | | -#define FDB_UPLINK_VPORT 0xffff |
---|
53 | 57 | |
---|
54 | 58 | #define MLX5_MIN_BW_SHARE 1 |
---|
55 | 59 | |
---|
.. | .. |
---|
59 | 63 | #define mlx5_esw_has_fwd_fdb(dev) \ |
---|
60 | 64 | MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_to_table) |
---|
61 | 65 | |
---|
| 66 | +#define esw_chains(esw) \ |
---|
| 67 | + ((esw)->fdb_table.offloads.esw_chains_priv) |
---|
| 68 | + |
---|
62 | 69 | struct vport_ingress { |
---|
63 | 70 | struct mlx5_flow_table *acl; |
---|
64 | | - struct mlx5_flow_group *allow_untagged_spoofchk_grp; |
---|
65 | | - struct mlx5_flow_group *allow_spoofchk_only_grp; |
---|
66 | | - struct mlx5_flow_group *allow_untagged_only_grp; |
---|
67 | | - struct mlx5_flow_group *drop_grp; |
---|
68 | | - struct mlx5_flow_handle *allow_rule; |
---|
69 | | - struct mlx5_flow_handle *drop_rule; |
---|
70 | | - struct mlx5_fc *drop_counter; |
---|
| 71 | + struct mlx5_flow_handle *allow_rule; |
---|
| 72 | + struct { |
---|
| 73 | + struct mlx5_flow_group *allow_spoofchk_only_grp; |
---|
| 74 | + struct mlx5_flow_group *allow_untagged_spoofchk_grp; |
---|
| 75 | + struct mlx5_flow_group *allow_untagged_only_grp; |
---|
| 76 | + struct mlx5_flow_group *drop_grp; |
---|
| 77 | + struct mlx5_flow_handle *drop_rule; |
---|
| 78 | + struct mlx5_fc *drop_counter; |
---|
| 79 | + } legacy; |
---|
| 80 | + struct { |
---|
| 81 | + /* Optional group to add an FTE to do internal priority |
---|
| 82 | + * tagging on ingress packets. |
---|
| 83 | + */ |
---|
| 84 | + struct mlx5_flow_group *metadata_prio_tag_grp; |
---|
| 85 | + /* Group to add default match-all FTE entry to tag ingress |
---|
| 86 | + * packet with metadata. |
---|
| 87 | + */ |
---|
| 88 | + struct mlx5_flow_group *metadata_allmatch_grp; |
---|
| 89 | + struct mlx5_modify_hdr *modify_metadata; |
---|
| 90 | + struct mlx5_flow_handle *modify_metadata_rule; |
---|
| 91 | + } offloads; |
---|
71 | 92 | }; |
---|
72 | 93 | |
---|
73 | 94 | struct vport_egress { |
---|
74 | 95 | struct mlx5_flow_table *acl; |
---|
75 | | - struct mlx5_flow_group *allowed_vlans_grp; |
---|
76 | | - struct mlx5_flow_group *drop_grp; |
---|
77 | 96 | struct mlx5_flow_handle *allowed_vlan; |
---|
78 | | - struct mlx5_flow_handle *drop_rule; |
---|
79 | | - struct mlx5_fc *drop_counter; |
---|
| 97 | + struct mlx5_flow_group *vlan_grp; |
---|
| 98 | + union { |
---|
| 99 | + struct { |
---|
| 100 | + struct mlx5_flow_group *drop_grp; |
---|
| 101 | + struct mlx5_flow_handle *drop_rule; |
---|
| 102 | + struct mlx5_fc *drop_counter; |
---|
| 103 | + } legacy; |
---|
| 104 | + struct { |
---|
| 105 | + struct mlx5_flow_group *fwd_grp; |
---|
| 106 | + struct mlx5_flow_handle *fwd_rule; |
---|
| 107 | + } offloads; |
---|
| 108 | + }; |
---|
80 | 109 | }; |
---|
81 | 110 | |
---|
82 | 111 | struct mlx5_vport_drop_stats { |
---|
.. | .. |
---|
96 | 125 | bool trusted; |
---|
97 | 126 | }; |
---|
98 | 127 | |
---|
| 128 | +/* Vport context events */ |
---|
| 129 | +enum mlx5_eswitch_vport_event { |
---|
| 130 | + MLX5_VPORT_UC_ADDR_CHANGE = BIT(0), |
---|
| 131 | + MLX5_VPORT_MC_ADDR_CHANGE = BIT(1), |
---|
| 132 | + MLX5_VPORT_PROMISC_CHANGE = BIT(3), |
---|
| 133 | +}; |
---|
| 134 | + |
---|
99 | 135 | struct mlx5_vport { |
---|
100 | 136 | struct mlx5_core_dev *dev; |
---|
101 | 137 | int vport; |
---|
.. | .. |
---|
107 | 143 | |
---|
108 | 144 | struct vport_ingress ingress; |
---|
109 | 145 | struct vport_egress egress; |
---|
| 146 | + u32 default_metadata; |
---|
| 147 | + u32 metadata; |
---|
110 | 148 | |
---|
111 | 149 | struct mlx5_vport_info info; |
---|
112 | 150 | |
---|
.. | .. |
---|
117 | 155 | } qos; |
---|
118 | 156 | |
---|
119 | 157 | bool enabled; |
---|
120 | | - u16 enabled_events; |
---|
| 158 | + enum mlx5_eswitch_vport_event enabled_events; |
---|
| 159 | + struct devlink_port *dl_port; |
---|
121 | 160 | }; |
---|
122 | 161 | |
---|
123 | 162 | struct mlx5_eswitch_fdb { |
---|
.. | .. |
---|
127 | 166 | struct mlx5_flow_group *addr_grp; |
---|
128 | 167 | struct mlx5_flow_group *allmulti_grp; |
---|
129 | 168 | struct mlx5_flow_group *promisc_grp; |
---|
| 169 | + struct mlx5_flow_table *vepa_fdb; |
---|
| 170 | + struct mlx5_flow_handle *vepa_uplink_rule; |
---|
| 171 | + struct mlx5_flow_handle *vepa_star_rule; |
---|
130 | 172 | } legacy; |
---|
131 | 173 | |
---|
132 | 174 | struct offloads_fdb { |
---|
133 | | - struct mlx5_flow_table *fast_fdb; |
---|
134 | | - struct mlx5_flow_table *fwd_fdb; |
---|
| 175 | + struct mlx5_flow_namespace *ns; |
---|
135 | 176 | struct mlx5_flow_table *slow_fdb; |
---|
136 | 177 | struct mlx5_flow_group *send_to_vport_grp; |
---|
| 178 | + struct mlx5_flow_group *peer_miss_grp; |
---|
| 179 | + struct mlx5_flow_handle **peer_miss_rules; |
---|
137 | 180 | struct mlx5_flow_group *miss_grp; |
---|
138 | 181 | struct mlx5_flow_handle *miss_rule_uni; |
---|
139 | 182 | struct mlx5_flow_handle *miss_rule_multi; |
---|
140 | 183 | int vlan_push_pop_refcount; |
---|
| 184 | + |
---|
| 185 | + struct mlx5_fs_chains *esw_chains_priv; |
---|
| 186 | + struct { |
---|
| 187 | + DECLARE_HASHTABLE(table, 8); |
---|
| 188 | + /* Protects vports.table */ |
---|
| 189 | + struct mutex lock; |
---|
| 190 | + } vports; |
---|
| 191 | + |
---|
141 | 192 | } offloads; |
---|
142 | 193 | }; |
---|
| 194 | + u32 flags; |
---|
143 | 195 | }; |
---|
144 | 196 | |
---|
145 | 197 | struct mlx5_esw_offload { |
---|
| 198 | + struct mlx5_flow_table *ft_offloads_restore; |
---|
| 199 | + struct mlx5_flow_group *restore_group; |
---|
| 200 | + struct mlx5_modify_hdr *restore_copy_hdr_id; |
---|
| 201 | + |
---|
146 | 202 | struct mlx5_flow_table *ft_offloads; |
---|
147 | 203 | struct mlx5_flow_group *vport_rx_group; |
---|
148 | 204 | struct mlx5_eswitch_rep *vport_reps; |
---|
| 205 | + struct list_head peer_flows; |
---|
| 206 | + struct mutex peer_mutex; |
---|
| 207 | + struct mutex encap_tbl_lock; /* protects encap_tbl */ |
---|
149 | 208 | DECLARE_HASHTABLE(encap_tbl, 8); |
---|
150 | | - DECLARE_HASHTABLE(mod_hdr_tbl, 8); |
---|
| 209 | + struct mutex decap_tbl_lock; /* protects decap_tbl */ |
---|
| 210 | + DECLARE_HASHTABLE(decap_tbl, 8); |
---|
| 211 | + struct mod_hdr_tbl mod_hdr; |
---|
| 212 | + DECLARE_HASHTABLE(termtbl_tbl, 8); |
---|
| 213 | + struct mutex termtbl_mutex; /* protects termtbl hash */ |
---|
| 214 | + const struct mlx5_eswitch_rep_ops *rep_ops[NUM_REP_TYPES]; |
---|
151 | 215 | u8 inline_mode; |
---|
152 | | - u64 num_flows; |
---|
153 | | - u8 encap; |
---|
| 216 | + atomic64_t num_flows; |
---|
| 217 | + enum devlink_eswitch_encap_mode encap; |
---|
| 218 | + struct ida vport_metadata_ida; |
---|
| 219 | + unsigned int host_number; /* ECPF supports one external host */ |
---|
154 | 220 | }; |
---|
155 | 221 | |
---|
156 | 222 | /* E-Switch MC FDB table hash node */ |
---|
.. | .. |
---|
160 | 226 | u32 refcnt; |
---|
161 | 227 | }; |
---|
162 | 228 | |
---|
| 229 | +struct mlx5_host_work { |
---|
| 230 | + struct work_struct work; |
---|
| 231 | + struct mlx5_eswitch *esw; |
---|
| 232 | +}; |
---|
| 233 | + |
---|
| 234 | +struct mlx5_esw_functions { |
---|
| 235 | + struct mlx5_nb nb; |
---|
| 236 | + u16 num_vfs; |
---|
| 237 | +}; |
---|
| 238 | + |
---|
| 239 | +enum { |
---|
| 240 | + MLX5_ESWITCH_VPORT_MATCH_METADATA = BIT(0), |
---|
| 241 | + MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED = BIT(1), |
---|
| 242 | +}; |
---|
| 243 | + |
---|
163 | 244 | struct mlx5_eswitch { |
---|
164 | 245 | struct mlx5_core_dev *dev; |
---|
| 246 | + struct mlx5_nb nb; |
---|
165 | 247 | struct mlx5_eswitch_fdb fdb_table; |
---|
| 248 | + /* legacy data structures */ |
---|
166 | 249 | struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE]; |
---|
| 250 | + struct esw_mc_addr mc_promisc; |
---|
| 251 | + /* end of legacy */ |
---|
167 | 252 | struct workqueue_struct *work_queue; |
---|
168 | 253 | struct mlx5_vport *vports; |
---|
| 254 | + u32 flags; |
---|
169 | 255 | int total_vports; |
---|
170 | 256 | int enabled_vports; |
---|
171 | 257 | /* Synchronize between vport change events |
---|
172 | 258 | * and async SRIOV admin state changes |
---|
173 | 259 | */ |
---|
174 | 260 | struct mutex state_lock; |
---|
175 | | - struct esw_mc_addr mc_promisc; |
---|
| 261 | + |
---|
| 262 | + /* Protects eswitch mode change that occurs via one or more |
---|
| 263 | + * user commands, i.e. sriov state change, devlink commands. |
---|
| 264 | + */ |
---|
| 265 | + struct rw_semaphore mode_lock; |
---|
176 | 266 | |
---|
177 | 267 | struct { |
---|
178 | 268 | bool enabled; |
---|
.. | .. |
---|
181 | 271 | |
---|
182 | 272 | struct mlx5_esw_offload offloads; |
---|
183 | 273 | int mode; |
---|
| 274 | + u16 manager_vport; |
---|
| 275 | + u16 first_host_vport; |
---|
| 276 | + struct mlx5_esw_functions esw_funcs; |
---|
| 277 | + struct { |
---|
| 278 | + u32 large_group_num; |
---|
| 279 | + } params; |
---|
184 | 280 | }; |
---|
185 | 281 | |
---|
186 | | -void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports); |
---|
187 | | -int esw_offloads_init(struct mlx5_eswitch *esw, int nvports); |
---|
| 282 | +void esw_offloads_disable(struct mlx5_eswitch *esw); |
---|
| 283 | +int esw_offloads_enable(struct mlx5_eswitch *esw); |
---|
188 | 284 | void esw_offloads_cleanup_reps(struct mlx5_eswitch *esw); |
---|
189 | 285 | int esw_offloads_init_reps(struct mlx5_eswitch *esw); |
---|
| 286 | + |
---|
| 287 | +u32 mlx5_esw_match_metadata_alloc(struct mlx5_eswitch *esw); |
---|
| 288 | +void mlx5_esw_match_metadata_free(struct mlx5_eswitch *esw, u32 metadata); |
---|
| 289 | + |
---|
| 290 | +int mlx5_esw_modify_vport_rate(struct mlx5_eswitch *esw, u16 vport_num, |
---|
| 291 | + u32 rate_mbps); |
---|
190 | 292 | |
---|
191 | 293 | /* E-Switch API */ |
---|
192 | 294 | int mlx5_eswitch_init(struct mlx5_core_dev *dev); |
---|
193 | 295 | void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); |
---|
194 | | -void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe); |
---|
195 | | -int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode); |
---|
196 | | -void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw); |
---|
| 296 | + |
---|
| 297 | +#define MLX5_ESWITCH_IGNORE_NUM_VFS (-1) |
---|
| 298 | +int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int mode, int num_vfs); |
---|
| 299 | +int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs); |
---|
| 300 | +void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf); |
---|
| 301 | +void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf); |
---|
197 | 302 | int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, |
---|
198 | | - int vport, u8 mac[ETH_ALEN]); |
---|
| 303 | + u16 vport, const u8 *mac); |
---|
199 | 304 | int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, |
---|
200 | | - int vport, int link_state); |
---|
| 305 | + u16 vport, int link_state); |
---|
201 | 306 | int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, |
---|
202 | | - int vport, u16 vlan, u8 qos); |
---|
| 307 | + u16 vport, u16 vlan, u8 qos); |
---|
203 | 308 | int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, |
---|
204 | | - int vport, bool spoofchk); |
---|
| 309 | + u16 vport, bool spoofchk); |
---|
205 | 310 | int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, |
---|
206 | | - int vport_num, bool setting); |
---|
207 | | -int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport, |
---|
| 311 | + u16 vport_num, bool setting); |
---|
| 312 | +int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, u16 vport, |
---|
208 | 313 | u32 max_rate, u32 min_rate); |
---|
| 314 | +int mlx5_eswitch_set_vepa(struct mlx5_eswitch *esw, u8 setting); |
---|
| 315 | +int mlx5_eswitch_get_vepa(struct mlx5_eswitch *esw, u8 *setting); |
---|
209 | 316 | int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, |
---|
210 | | - int vport, struct ifla_vf_info *ivi); |
---|
| 317 | + u16 vport, struct ifla_vf_info *ivi); |
---|
211 | 318 | int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, |
---|
212 | | - int vport, |
---|
| 319 | + u16 vport, |
---|
213 | 320 | struct ifla_vf_stats *vf_stats); |
---|
214 | 321 | void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule); |
---|
215 | 322 | |
---|
| 323 | +int mlx5_eswitch_modify_esw_vport_context(struct mlx5_core_dev *dev, u16 vport, |
---|
| 324 | + bool other_vport, void *in); |
---|
| 325 | + |
---|
216 | 326 | struct mlx5_flow_spec; |
---|
217 | 327 | struct mlx5_esw_flow_attr; |
---|
| 328 | +struct mlx5_termtbl_handle; |
---|
| 329 | + |
---|
| 330 | +bool |
---|
| 331 | +mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw, |
---|
| 332 | + struct mlx5_flow_attr *attr, |
---|
| 333 | + struct mlx5_flow_act *flow_act, |
---|
| 334 | + struct mlx5_flow_spec *spec); |
---|
| 335 | + |
---|
| 336 | +struct mlx5_flow_handle * |
---|
| 337 | +mlx5_eswitch_add_termtbl_rule(struct mlx5_eswitch *esw, |
---|
| 338 | + struct mlx5_flow_table *ft, |
---|
| 339 | + struct mlx5_flow_spec *spec, |
---|
| 340 | + struct mlx5_esw_flow_attr *attr, |
---|
| 341 | + struct mlx5_flow_act *flow_act, |
---|
| 342 | + struct mlx5_flow_destination *dest, |
---|
| 343 | + int num_dest); |
---|
| 344 | + |
---|
| 345 | +void |
---|
| 346 | +mlx5_eswitch_termtbl_put(struct mlx5_eswitch *esw, |
---|
| 347 | + struct mlx5_termtbl_handle *tt); |
---|
218 | 348 | |
---|
219 | 349 | struct mlx5_flow_handle * |
---|
220 | 350 | mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, |
---|
221 | 351 | struct mlx5_flow_spec *spec, |
---|
222 | | - struct mlx5_esw_flow_attr *attr); |
---|
| 352 | + struct mlx5_flow_attr *attr); |
---|
223 | 353 | struct mlx5_flow_handle * |
---|
224 | 354 | mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw, |
---|
225 | 355 | struct mlx5_flow_spec *spec, |
---|
226 | | - struct mlx5_esw_flow_attr *attr); |
---|
| 356 | + struct mlx5_flow_attr *attr); |
---|
227 | 357 | void |
---|
228 | 358 | mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw, |
---|
229 | 359 | struct mlx5_flow_handle *rule, |
---|
230 | | - struct mlx5_esw_flow_attr *attr); |
---|
| 360 | + struct mlx5_flow_attr *attr); |
---|
| 361 | +void |
---|
| 362 | +mlx5_eswitch_del_fwd_rule(struct mlx5_eswitch *esw, |
---|
| 363 | + struct mlx5_flow_handle *rule, |
---|
| 364 | + struct mlx5_flow_attr *attr); |
---|
231 | 365 | |
---|
232 | 366 | struct mlx5_flow_handle * |
---|
233 | | -mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn); |
---|
| 367 | +mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, u16 vport, |
---|
| 368 | + struct mlx5_flow_destination *dest); |
---|
234 | 369 | |
---|
235 | 370 | enum { |
---|
236 | 371 | SET_VLAN_STRIP = BIT(0), |
---|
.. | .. |
---|
247 | 382 | /* current maximum for flow based vport multicasting */ |
---|
248 | 383 | #define MLX5_MAX_FLOW_FWD_VPORTS 2 |
---|
249 | 384 | |
---|
| 385 | +enum { |
---|
| 386 | + MLX5_ESW_DEST_ENCAP = BIT(0), |
---|
| 387 | + MLX5_ESW_DEST_ENCAP_VALID = BIT(1), |
---|
| 388 | +}; |
---|
| 389 | + |
---|
| 390 | +enum { |
---|
| 391 | + MLX5_ESW_ATTR_FLAG_VLAN_HANDLED = BIT(0), |
---|
| 392 | + MLX5_ESW_ATTR_FLAG_SLOW_PATH = BIT(1), |
---|
| 393 | + MLX5_ESW_ATTR_FLAG_NO_IN_PORT = BIT(2), |
---|
| 394 | +}; |
---|
| 395 | + |
---|
250 | 396 | struct mlx5_esw_flow_attr { |
---|
251 | 397 | struct mlx5_eswitch_rep *in_rep; |
---|
252 | | - struct mlx5_eswitch_rep *out_rep[MLX5_MAX_FLOW_FWD_VPORTS]; |
---|
253 | | - struct mlx5_core_dev *out_mdev[MLX5_MAX_FLOW_FWD_VPORTS]; |
---|
254 | 398 | struct mlx5_core_dev *in_mdev; |
---|
| 399 | + struct mlx5_core_dev *counter_dev; |
---|
255 | 400 | |
---|
256 | | - int mirror_count; |
---|
| 401 | + int split_count; |
---|
257 | 402 | int out_count; |
---|
258 | 403 | |
---|
259 | | - int action; |
---|
260 | 404 | __be16 vlan_proto[MLX5_FS_VLAN_DEPTH]; |
---|
261 | 405 | u16 vlan_vid[MLX5_FS_VLAN_DEPTH]; |
---|
262 | 406 | u8 vlan_prio[MLX5_FS_VLAN_DEPTH]; |
---|
263 | 407 | u8 total_vlan; |
---|
264 | | - bool vlan_handled; |
---|
265 | | - u32 encap_id; |
---|
266 | | - u32 mod_hdr_id; |
---|
267 | | - u8 match_level; |
---|
268 | | - struct mlx5e_tc_flow_parse_attr *parse_attr; |
---|
| 408 | + struct { |
---|
| 409 | + u32 flags; |
---|
| 410 | + struct mlx5_eswitch_rep *rep; |
---|
| 411 | + struct mlx5_pkt_reformat *pkt_reformat; |
---|
| 412 | + struct mlx5_core_dev *mdev; |
---|
| 413 | + struct mlx5_termtbl_handle *termtbl; |
---|
| 414 | + } dests[MLX5_MAX_FLOW_FWD_VPORTS]; |
---|
| 415 | + struct mlx5_pkt_reformat *decap_pkt_reformat; |
---|
269 | 416 | }; |
---|
270 | 417 | |
---|
271 | | -int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode); |
---|
| 418 | +int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, |
---|
| 419 | + struct netlink_ext_ack *extack); |
---|
272 | 420 | int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode); |
---|
273 | | -int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode); |
---|
| 421 | +int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode, |
---|
| 422 | + struct netlink_ext_ack *extack); |
---|
274 | 423 | int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode); |
---|
275 | | -int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode); |
---|
276 | | -int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); |
---|
277 | | -int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); |
---|
| 424 | +int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, |
---|
| 425 | + enum devlink_eswitch_encap_mode encap, |
---|
| 426 | + struct netlink_ext_ack *extack); |
---|
| 427 | +int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, |
---|
| 428 | + enum devlink_eswitch_encap_mode *encap); |
---|
| 429 | +int mlx5_devlink_port_function_hw_addr_get(struct devlink *devlink, |
---|
| 430 | + struct devlink_port *port, |
---|
| 431 | + u8 *hw_addr, int *hw_addr_len, |
---|
| 432 | + struct netlink_ext_ack *extack); |
---|
| 433 | +int mlx5_devlink_port_function_hw_addr_set(struct devlink *devlink, |
---|
| 434 | + struct devlink_port *port, |
---|
| 435 | + const u8 *hw_addr, int hw_addr_len, |
---|
| 436 | + struct netlink_ext_ack *extack); |
---|
| 437 | + |
---|
278 | 438 | void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); |
---|
279 | 439 | |
---|
280 | 440 | int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, |
---|
281 | | - struct mlx5_esw_flow_attr *attr); |
---|
| 441 | + struct mlx5_flow_attr *attr); |
---|
282 | 442 | int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, |
---|
283 | | - struct mlx5_esw_flow_attr *attr); |
---|
| 443 | + struct mlx5_flow_attr *attr); |
---|
284 | 444 | int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, |
---|
285 | | - int vport, u16 vlan, u8 qos, u8 set_flags); |
---|
| 445 | + u16 vport, u16 vlan, u8 qos, u8 set_flags); |
---|
| 446 | + |
---|
| 447 | +static inline bool mlx5_esw_qos_enabled(struct mlx5_eswitch *esw) |
---|
| 448 | +{ |
---|
| 449 | + return esw->qos.enabled; |
---|
| 450 | +} |
---|
286 | 451 | |
---|
287 | 452 | static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev, |
---|
288 | 453 | u8 vlan_depth) |
---|
.. | .. |
---|
297 | 462 | MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan_2); |
---|
298 | 463 | } |
---|
299 | 464 | |
---|
| 465 | +bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, |
---|
| 466 | + struct mlx5_core_dev *dev1); |
---|
| 467 | +bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0, |
---|
| 468 | + struct mlx5_core_dev *dev1); |
---|
| 469 | + |
---|
| 470 | +const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev); |
---|
| 471 | + |
---|
300 | 472 | #define MLX5_DEBUG_ESWITCH_MASK BIT(3) |
---|
301 | 473 | |
---|
302 | | -#define esw_info(dev, format, ...) \ |
---|
303 | | - pr_info("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__) |
---|
| 474 | +#define esw_info(__dev, format, ...) \ |
---|
| 475 | + dev_info((__dev)->device, "E-Switch: " format, ##__VA_ARGS__) |
---|
304 | 476 | |
---|
305 | | -#define esw_warn(dev, format, ...) \ |
---|
306 | | - pr_warn("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__) |
---|
| 477 | +#define esw_warn(__dev, format, ...) \ |
---|
| 478 | + dev_warn((__dev)->device, "E-Switch: " format, ##__VA_ARGS__) |
---|
307 | 479 | |
---|
308 | 480 | #define esw_debug(dev, format, ...) \ |
---|
309 | 481 | mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__) |
---|
| 482 | + |
---|
| 483 | +/* The returned number is valid only when the dev is eswitch manager. */ |
---|
| 484 | +static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev) |
---|
| 485 | +{ |
---|
| 486 | + return mlx5_core_is_ecpf_esw_manager(dev) ? |
---|
| 487 | + MLX5_VPORT_ECPF : MLX5_VPORT_PF; |
---|
| 488 | +} |
---|
| 489 | + |
---|
| 490 | +static inline bool |
---|
| 491 | +mlx5_esw_is_manager_vport(const struct mlx5_eswitch *esw, u16 vport_num) |
---|
| 492 | +{ |
---|
| 493 | + return esw->manager_vport == vport_num; |
---|
| 494 | +} |
---|
| 495 | + |
---|
| 496 | +static inline u16 mlx5_eswitch_first_host_vport_num(struct mlx5_core_dev *dev) |
---|
| 497 | +{ |
---|
| 498 | + return mlx5_core_is_ecpf_esw_manager(dev) ? |
---|
| 499 | + MLX5_VPORT_PF : MLX5_VPORT_FIRST_VF; |
---|
| 500 | +} |
---|
| 501 | + |
---|
| 502 | +static inline bool mlx5_eswitch_is_funcs_handler(const struct mlx5_core_dev *dev) |
---|
| 503 | +{ |
---|
| 504 | + return mlx5_core_is_ecpf_esw_manager(dev); |
---|
| 505 | +} |
---|
| 506 | + |
---|
| 507 | +static inline int mlx5_eswitch_uplink_idx(struct mlx5_eswitch *esw) |
---|
| 508 | +{ |
---|
| 509 | + /* Uplink always locate at the last element of the array.*/ |
---|
| 510 | + return esw->total_vports - 1; |
---|
| 511 | +} |
---|
| 512 | + |
---|
| 513 | +static inline int mlx5_eswitch_ecpf_idx(struct mlx5_eswitch *esw) |
---|
| 514 | +{ |
---|
| 515 | + return esw->total_vports - 2; |
---|
| 516 | +} |
---|
| 517 | + |
---|
| 518 | +static inline int mlx5_eswitch_vport_num_to_index(struct mlx5_eswitch *esw, |
---|
| 519 | + u16 vport_num) |
---|
| 520 | +{ |
---|
| 521 | + if (vport_num == MLX5_VPORT_ECPF) { |
---|
| 522 | + if (!mlx5_ecpf_vport_exists(esw->dev)) |
---|
| 523 | + esw_warn(esw->dev, "ECPF vport doesn't exist!\n"); |
---|
| 524 | + return mlx5_eswitch_ecpf_idx(esw); |
---|
| 525 | + } |
---|
| 526 | + |
---|
| 527 | + if (vport_num == MLX5_VPORT_UPLINK) |
---|
| 528 | + return mlx5_eswitch_uplink_idx(esw); |
---|
| 529 | + |
---|
| 530 | + return vport_num; |
---|
| 531 | +} |
---|
| 532 | + |
---|
| 533 | +static inline u16 mlx5_eswitch_index_to_vport_num(struct mlx5_eswitch *esw, |
---|
| 534 | + int index) |
---|
| 535 | +{ |
---|
| 536 | + if (index == mlx5_eswitch_ecpf_idx(esw) && |
---|
| 537 | + mlx5_ecpf_vport_exists(esw->dev)) |
---|
| 538 | + return MLX5_VPORT_ECPF; |
---|
| 539 | + |
---|
| 540 | + if (index == mlx5_eswitch_uplink_idx(esw)) |
---|
| 541 | + return MLX5_VPORT_UPLINK; |
---|
| 542 | + |
---|
| 543 | + return index; |
---|
| 544 | +} |
---|
| 545 | + |
---|
| 546 | +static inline unsigned int |
---|
| 547 | +mlx5_esw_vport_to_devlink_port_index(const struct mlx5_core_dev *dev, |
---|
| 548 | + u16 vport_num) |
---|
| 549 | +{ |
---|
| 550 | + return (MLX5_CAP_GEN(dev, vhca_id) << 16) | vport_num; |
---|
| 551 | +} |
---|
| 552 | + |
---|
| 553 | +static inline u16 |
---|
| 554 | +mlx5_esw_devlink_port_index_to_vport_num(unsigned int dl_port_index) |
---|
| 555 | +{ |
---|
| 556 | + return dl_port_index & 0xffff; |
---|
| 557 | +} |
---|
| 558 | + |
---|
| 559 | +/* TODO: This mlx5e_tc function shouldn't be called by eswitch */ |
---|
| 560 | +void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw); |
---|
| 561 | + |
---|
| 562 | +/* The vport getter/iterator are only valid after esw->total_vports |
---|
| 563 | + * and vport->vport are initialized in mlx5_eswitch_init. |
---|
| 564 | + */ |
---|
| 565 | +#define mlx5_esw_for_all_vports(esw, i, vport) \ |
---|
| 566 | + for ((i) = MLX5_VPORT_PF; \ |
---|
| 567 | + (vport) = &(esw)->vports[i], \ |
---|
| 568 | + (i) < (esw)->total_vports; (i)++) |
---|
| 569 | + |
---|
| 570 | +#define mlx5_esw_for_all_vports_reverse(esw, i, vport) \ |
---|
| 571 | + for ((i) = (esw)->total_vports - 1; \ |
---|
| 572 | + (vport) = &(esw)->vports[i], \ |
---|
| 573 | + (i) >= MLX5_VPORT_PF; (i)--) |
---|
| 574 | + |
---|
| 575 | +#define mlx5_esw_for_each_vf_vport(esw, i, vport, nvfs) \ |
---|
| 576 | + for ((i) = MLX5_VPORT_FIRST_VF; \ |
---|
| 577 | + (vport) = &(esw)->vports[(i)], \ |
---|
| 578 | + (i) <= (nvfs); (i)++) |
---|
| 579 | + |
---|
| 580 | +#define mlx5_esw_for_each_vf_vport_reverse(esw, i, vport, nvfs) \ |
---|
| 581 | + for ((i) = (nvfs); \ |
---|
| 582 | + (vport) = &(esw)->vports[(i)], \ |
---|
| 583 | + (i) >= MLX5_VPORT_FIRST_VF; (i)--) |
---|
| 584 | + |
---|
| 585 | +/* The rep getter/iterator are only valid after esw->total_vports |
---|
| 586 | + * and vport->vport are initialized in mlx5_eswitch_init. |
---|
| 587 | + */ |
---|
| 588 | +#define mlx5_esw_for_all_reps(esw, i, rep) \ |
---|
| 589 | + for ((i) = MLX5_VPORT_PF; \ |
---|
| 590 | + (rep) = &(esw)->offloads.vport_reps[i], \ |
---|
| 591 | + (i) < (esw)->total_vports; (i)++) |
---|
| 592 | + |
---|
| 593 | +#define mlx5_esw_for_each_vf_rep(esw, i, rep, nvfs) \ |
---|
| 594 | + for ((i) = MLX5_VPORT_FIRST_VF; \ |
---|
| 595 | + (rep) = &(esw)->offloads.vport_reps[i], \ |
---|
| 596 | + (i) <= (nvfs); (i)++) |
---|
| 597 | + |
---|
| 598 | +#define mlx5_esw_for_each_vf_rep_reverse(esw, i, rep, nvfs) \ |
---|
| 599 | + for ((i) = (nvfs); \ |
---|
| 600 | + (rep) = &(esw)->offloads.vport_reps[i], \ |
---|
| 601 | + (i) >= MLX5_VPORT_FIRST_VF; (i)--) |
---|
| 602 | + |
---|
| 603 | +#define mlx5_esw_for_each_vf_vport_num(esw, vport, nvfs) \ |
---|
| 604 | + for ((vport) = MLX5_VPORT_FIRST_VF; (vport) <= (nvfs); (vport)++) |
---|
| 605 | + |
---|
| 606 | +#define mlx5_esw_for_each_vf_vport_num_reverse(esw, vport, nvfs) \ |
---|
| 607 | + for ((vport) = (nvfs); (vport) >= MLX5_VPORT_FIRST_VF; (vport)--) |
---|
| 608 | + |
---|
| 609 | +/* Includes host PF (vport 0) if it's not esw manager. */ |
---|
| 610 | +#define mlx5_esw_for_each_host_func_rep(esw, i, rep, nvfs) \ |
---|
| 611 | + for ((i) = (esw)->first_host_vport; \ |
---|
| 612 | + (rep) = &(esw)->offloads.vport_reps[i], \ |
---|
| 613 | + (i) <= (nvfs); (i)++) |
---|
| 614 | + |
---|
| 615 | +#define mlx5_esw_for_each_host_func_rep_reverse(esw, i, rep, nvfs) \ |
---|
| 616 | + for ((i) = (nvfs); \ |
---|
| 617 | + (rep) = &(esw)->offloads.vport_reps[i], \ |
---|
| 618 | + (i) >= (esw)->first_host_vport; (i)--) |
---|
| 619 | + |
---|
| 620 | +#define mlx5_esw_for_each_host_func_vport(esw, vport, nvfs) \ |
---|
| 621 | + for ((vport) = (esw)->first_host_vport; \ |
---|
| 622 | + (vport) <= (nvfs); (vport)++) |
---|
| 623 | + |
---|
| 624 | +#define mlx5_esw_for_each_host_func_vport_reverse(esw, vport, nvfs) \ |
---|
| 625 | + for ((vport) = (nvfs); \ |
---|
| 626 | + (vport) >= (esw)->first_host_vport; (vport)--) |
---|
| 627 | + |
---|
| 628 | +struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink); |
---|
| 629 | +struct mlx5_vport *__must_check |
---|
| 630 | +mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 631 | + |
---|
| 632 | +bool mlx5_eswitch_is_vf_vport(const struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 633 | + |
---|
| 634 | +int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type, void *data); |
---|
| 635 | + |
---|
| 636 | +int |
---|
| 637 | +mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, |
---|
| 638 | + enum mlx5_eswitch_vport_event enabled_events); |
---|
| 639 | +void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw); |
---|
| 640 | + |
---|
| 641 | +int |
---|
| 642 | +esw_vport_create_offloads_acl_tables(struct mlx5_eswitch *esw, |
---|
| 643 | + struct mlx5_vport *vport); |
---|
| 644 | +void |
---|
| 645 | +esw_vport_destroy_offloads_acl_tables(struct mlx5_eswitch *esw, |
---|
| 646 | + struct mlx5_vport *vport); |
---|
| 647 | + |
---|
| 648 | +int mlx5_esw_vport_tbl_get(struct mlx5_eswitch *esw); |
---|
| 649 | +void mlx5_esw_vport_tbl_put(struct mlx5_eswitch *esw); |
---|
| 650 | + |
---|
| 651 | +struct mlx5_flow_handle * |
---|
| 652 | +esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag); |
---|
| 653 | +u32 |
---|
| 654 | +esw_get_max_restore_tag(struct mlx5_eswitch *esw); |
---|
| 655 | + |
---|
| 656 | +int esw_offloads_load_rep(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 657 | +void esw_offloads_unload_rep(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 658 | + |
---|
| 659 | +int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num, |
---|
| 660 | + enum mlx5_eswitch_vport_event enabled_events); |
---|
| 661 | +void mlx5_eswitch_unload_vport(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 662 | + |
---|
| 663 | +int mlx5_eswitch_load_vf_vports(struct mlx5_eswitch *esw, u16 num_vfs, |
---|
| 664 | + enum mlx5_eswitch_vport_event enabled_events); |
---|
| 665 | +void mlx5_eswitch_unload_vf_vports(struct mlx5_eswitch *esw, u16 num_vfs); |
---|
| 666 | + |
---|
| 667 | +int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 668 | +void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch *esw, u16 vport_num); |
---|
| 669 | +struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u16 vport_num); |
---|
310 | 670 | #else /* CONFIG_MLX5_ESWITCH */ |
---|
311 | 671 | /* eswitch API stubs */ |
---|
312 | 672 | static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } |
---|
313 | 673 | static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {} |
---|
314 | | -static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {} |
---|
315 | | -static inline int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; } |
---|
316 | | -static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {} |
---|
| 674 | +static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { return 0; } |
---|
| 675 | +static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) {} |
---|
| 676 | +static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; } |
---|
| 677 | +static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; } |
---|
| 678 | +static inline |
---|
| 679 | +int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; } |
---|
| 680 | +static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) |
---|
| 681 | +{ |
---|
| 682 | + return ERR_PTR(-EOPNOTSUPP); |
---|
| 683 | +} |
---|
| 684 | + |
---|
| 685 | +static inline struct mlx5_flow_handle * |
---|
| 686 | +esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag) |
---|
| 687 | +{ |
---|
| 688 | + return ERR_PTR(-EOPNOTSUPP); |
---|
| 689 | +} |
---|
317 | 690 | #endif /* CONFIG_MLX5_ESWITCH */ |
---|
318 | 691 | |
---|
319 | 692 | #endif /* __MLX5_ESWITCH_H__ */ |
---|