2 * Copyright (c) 2015, Mellanox Technologies, Ltd. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #ifndef __MLX5_ESWITCH_H__
34 #define __MLX5_ESWITCH_H__
36 #include <linux/if_ether.h>
37 #include <linux/if_link.h>
38 #include <linux/atomic.h>
39 #include <linux/xarray.h>
40 #include <net/devlink.h>
41 #include <linux/mlx5/device.h>
42 #include <linux/mlx5/eswitch.h>
43 #include <linux/mlx5/vport.h>
44 #include <linux/mlx5/fs.h>
46 #include "lib/fs_chains.h"
50 #ifdef CONFIG_MLX5_ESWITCH
52 #define ESW_OFFLOADS_DEFAULT_NUM_GROUPS 15
54 #define MLX5_MAX_UC_PER_VPORT(dev) \
55 (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
57 #define MLX5_MAX_MC_PER_VPORT(dev) \
58 (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
60 #define MLX5_MIN_BW_SHARE 1
62 #define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \
63 min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit)
65 #define mlx5_esw_has_fwd_fdb(dev) \
66 MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_to_table)
68 #define esw_chains(esw) \
69 ((esw)->fdb_table.offloads.esw_chains_priv)
71 struct vport_ingress
{
72 struct mlx5_flow_table
*acl
;
73 struct mlx5_flow_handle
*allow_rule
;
75 struct mlx5_flow_group
*allow_spoofchk_only_grp
;
76 struct mlx5_flow_group
*allow_untagged_spoofchk_grp
;
77 struct mlx5_flow_group
*allow_untagged_only_grp
;
78 struct mlx5_flow_group
*drop_grp
;
79 struct mlx5_flow_handle
*drop_rule
;
80 struct mlx5_fc
*drop_counter
;
83 /* Optional group to add an FTE to do internal priority
84 * tagging on ingress packets.
86 struct mlx5_flow_group
*metadata_prio_tag_grp
;
87 /* Group to add default match-all FTE entry to tag ingress
88 * packet with metadata.
90 struct mlx5_flow_group
*metadata_allmatch_grp
;
91 struct mlx5_modify_hdr
*modify_metadata
;
92 struct mlx5_flow_handle
*modify_metadata_rule
;
97 struct mlx5_flow_table
*acl
;
98 struct mlx5_flow_handle
*allowed_vlan
;
99 struct mlx5_flow_group
*vlan_grp
;
102 struct mlx5_flow_group
*drop_grp
;
103 struct mlx5_flow_handle
*drop_rule
;
104 struct mlx5_fc
*drop_counter
;
107 struct mlx5_flow_group
*fwd_grp
;
108 struct mlx5_flow_handle
*fwd_rule
;
113 struct mlx5_vport_drop_stats
{
118 struct mlx5_vport_info
{
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),
136 struct mlx5_core_dev
*dev
;
138 struct hlist_head uc_list
[MLX5_L2_ADDR_HASH_SIZE
];
139 struct hlist_head mc_list
[MLX5_L2_ADDR_HASH_SIZE
];
140 struct mlx5_flow_handle
*promisc_rule
;
141 struct mlx5_flow_handle
*allmulti_rule
;
142 struct work_struct vport_change_handler
;
144 struct vport_ingress ingress
;
145 struct vport_egress egress
;
146 u32 default_metadata
;
149 struct mlx5_vport_info info
;
160 enum mlx5_eswitch_vport_event enabled_events
;
161 struct devlink_port
*dl_port
;
164 struct mlx5_esw_indir_table
;
166 struct mlx5_eswitch_fdb
{
169 struct mlx5_flow_table
*fdb
;
170 struct mlx5_flow_group
*addr_grp
;
171 struct mlx5_flow_group
*allmulti_grp
;
172 struct mlx5_flow_group
*promisc_grp
;
173 struct mlx5_flow_table
*vepa_fdb
;
174 struct mlx5_flow_handle
*vepa_uplink_rule
;
175 struct mlx5_flow_handle
*vepa_star_rule
;
178 struct offloads_fdb
{
179 struct mlx5_flow_namespace
*ns
;
180 struct mlx5_flow_table
*slow_fdb
;
181 struct mlx5_flow_group
*send_to_vport_grp
;
182 struct mlx5_flow_group
*send_to_vport_meta_grp
;
183 struct mlx5_flow_group
*peer_miss_grp
;
184 struct mlx5_flow_handle
**peer_miss_rules
;
185 struct mlx5_flow_group
*miss_grp
;
186 struct mlx5_flow_handle
**send_to_vport_meta_rules
;
187 struct mlx5_flow_handle
*miss_rule_uni
;
188 struct mlx5_flow_handle
*miss_rule_multi
;
189 int vlan_push_pop_refcount
;
191 struct mlx5_fs_chains
*esw_chains_priv
;
193 DECLARE_HASHTABLE(table
, 8);
194 /* Protects vports.table */
198 struct mlx5_esw_indir_table
*indir
;
205 struct mlx5_esw_offload
{
206 struct mlx5_flow_table
*ft_offloads_restore
;
207 struct mlx5_flow_group
*restore_group
;
208 struct mlx5_modify_hdr
*restore_copy_hdr_id
;
210 struct mlx5_flow_table
*ft_offloads
;
211 struct mlx5_flow_group
*vport_rx_group
;
212 struct mlx5_eswitch_rep
*vport_reps
;
213 struct list_head peer_flows
;
214 struct mutex peer_mutex
;
215 struct mutex encap_tbl_lock
; /* protects encap_tbl */
216 DECLARE_HASHTABLE(encap_tbl
, 8);
217 struct mutex decap_tbl_lock
; /* protects decap_tbl */
218 DECLARE_HASHTABLE(decap_tbl
, 8);
219 struct mod_hdr_tbl mod_hdr
;
220 DECLARE_HASHTABLE(termtbl_tbl
, 8);
221 struct mutex termtbl_mutex
; /* protects termtbl hash */
222 struct xarray vhca_map
;
223 const struct mlx5_eswitch_rep_ops
*rep_ops
[NUM_REP_TYPES
];
225 atomic64_t num_flows
;
226 enum devlink_eswitch_encap_mode encap
;
227 struct ida vport_metadata_ida
;
228 unsigned int host_number
; /* ECPF supports one external host */
231 /* E-Switch MC FDB table hash node */
232 struct esw_mc_addr
{ /* SRIOV only */
233 struct l2addr_node node
;
234 struct mlx5_flow_handle
*uplink_rule
; /* Forward to uplink rule */
238 struct mlx5_host_work
{
239 struct work_struct work
;
240 struct mlx5_eswitch
*esw
;
243 struct mlx5_esw_functions
{
249 MLX5_ESWITCH_VPORT_MATCH_METADATA
= BIT(0),
250 MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED
= BIT(1),
253 struct mlx5_eswitch
{
254 struct mlx5_core_dev
*dev
;
256 struct mlx5_eswitch_fdb fdb_table
;
257 /* legacy data structures */
258 struct hlist_head mc_table
[MLX5_L2_ADDR_HASH_SIZE
];
259 struct esw_mc_addr mc_promisc
;
261 struct workqueue_struct
*work_queue
;
262 struct mlx5_vport
*vports
;
266 /* Synchronize between vport change events
267 * and async SRIOV admin state changes
269 struct mutex state_lock
;
271 /* Protects eswitch mode change that occurs via one or more
272 * user commands, i.e. sriov state change, devlink commands.
274 struct rw_semaphore mode_lock
;
275 atomic64_t user_count
;
282 struct mlx5_esw_offload offloads
;
285 u16 first_host_vport
;
286 struct mlx5_esw_functions esw_funcs
;
290 struct blocking_notifier_head n_head
;
293 void esw_offloads_disable(struct mlx5_eswitch
*esw
);
294 int esw_offloads_enable(struct mlx5_eswitch
*esw
);
295 void esw_offloads_cleanup_reps(struct mlx5_eswitch
*esw
);
296 int esw_offloads_init_reps(struct mlx5_eswitch
*esw
);
298 u32
mlx5_esw_match_metadata_alloc(struct mlx5_eswitch
*esw
);
299 void mlx5_esw_match_metadata_free(struct mlx5_eswitch
*esw
, u32 metadata
);
301 int mlx5_esw_modify_vport_rate(struct mlx5_eswitch
*esw
, u16 vport_num
,
305 int mlx5_eswitch_init(struct mlx5_core_dev
*dev
);
306 void mlx5_eswitch_cleanup(struct mlx5_eswitch
*esw
);
308 #define MLX5_ESWITCH_IGNORE_NUM_VFS (-1)
309 int mlx5_eswitch_enable_locked(struct mlx5_eswitch
*esw
, int mode
, int num_vfs
);
310 int mlx5_eswitch_enable(struct mlx5_eswitch
*esw
, int num_vfs
);
311 void mlx5_eswitch_disable_locked(struct mlx5_eswitch
*esw
, bool clear_vf
);
312 void mlx5_eswitch_disable(struct mlx5_eswitch
*esw
, bool clear_vf
);
313 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch
*esw
,
314 u16 vport
, const u8
*mac
);
315 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch
*esw
,
316 u16 vport
, int link_state
);
317 int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch
*esw
,
318 u16 vport
, u16 vlan
, u8 qos
);
319 int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch
*esw
,
320 u16 vport
, bool spoofchk
);
321 int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch
*esw
,
322 u16 vport_num
, bool setting
);
323 int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch
*esw
, u16 vport
,
324 u32 max_rate
, u32 min_rate
);
325 int mlx5_eswitch_set_vepa(struct mlx5_eswitch
*esw
, u8 setting
);
326 int mlx5_eswitch_get_vepa(struct mlx5_eswitch
*esw
, u8
*setting
);
327 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch
*esw
,
328 u16 vport
, struct ifla_vf_info
*ivi
);
329 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch
*esw
,
331 struct ifla_vf_stats
*vf_stats
);
332 void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle
*rule
);
334 int mlx5_eswitch_modify_esw_vport_context(struct mlx5_core_dev
*dev
, u16 vport
,
335 bool other_vport
, void *in
);
337 struct mlx5_flow_spec
;
338 struct mlx5_esw_flow_attr
;
339 struct mlx5_termtbl_handle
;
342 mlx5_eswitch_termtbl_required(struct mlx5_eswitch
*esw
,
343 struct mlx5_flow_attr
*attr
,
344 struct mlx5_flow_act
*flow_act
,
345 struct mlx5_flow_spec
*spec
);
347 struct mlx5_flow_handle
*
348 mlx5_eswitch_add_termtbl_rule(struct mlx5_eswitch
*esw
,
349 struct mlx5_flow_table
*ft
,
350 struct mlx5_flow_spec
*spec
,
351 struct mlx5_esw_flow_attr
*attr
,
352 struct mlx5_flow_act
*flow_act
,
353 struct mlx5_flow_destination
*dest
,
357 mlx5_eswitch_termtbl_put(struct mlx5_eswitch
*esw
,
358 struct mlx5_termtbl_handle
*tt
);
360 struct mlx5_flow_handle
*
361 mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch
*esw
,
362 struct mlx5_flow_spec
*spec
,
363 struct mlx5_flow_attr
*attr
);
364 struct mlx5_flow_handle
*
365 mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch
*esw
,
366 struct mlx5_flow_spec
*spec
,
367 struct mlx5_flow_attr
*attr
);
369 mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch
*esw
,
370 struct mlx5_flow_handle
*rule
,
371 struct mlx5_flow_attr
*attr
);
373 mlx5_eswitch_del_fwd_rule(struct mlx5_eswitch
*esw
,
374 struct mlx5_flow_handle
*rule
,
375 struct mlx5_flow_attr
*attr
);
377 struct mlx5_flow_handle
*
378 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch
*esw
, u16 vport
,
379 struct mlx5_flow_destination
*dest
);
382 SET_VLAN_STRIP
= BIT(0),
383 SET_VLAN_INSERT
= BIT(1)
386 enum mlx5_flow_match_level
{
387 MLX5_MATCH_NONE
= MLX5_INLINE_MODE_NONE
,
388 MLX5_MATCH_L2
= MLX5_INLINE_MODE_L2
,
389 MLX5_MATCH_L3
= MLX5_INLINE_MODE_IP
,
390 MLX5_MATCH_L4
= MLX5_INLINE_MODE_TCP_UDP
,
393 /* current maximum for flow based vport multicasting */
394 #define MLX5_MAX_FLOW_FWD_VPORTS 2
397 MLX5_ESW_DEST_ENCAP
= BIT(0),
398 MLX5_ESW_DEST_ENCAP_VALID
= BIT(1),
399 MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE
= BIT(2),
403 MLX5_ESW_ATTR_FLAG_VLAN_HANDLED
= BIT(0),
404 MLX5_ESW_ATTR_FLAG_SLOW_PATH
= BIT(1),
405 MLX5_ESW_ATTR_FLAG_NO_IN_PORT
= BIT(2),
406 MLX5_ESW_ATTR_FLAG_SRC_REWRITE
= BIT(3),
409 struct mlx5_esw_flow_attr
{
410 struct mlx5_eswitch_rep
*in_rep
;
411 struct mlx5_core_dev
*in_mdev
;
412 struct mlx5_core_dev
*counter_dev
;
417 __be16 vlan_proto
[MLX5_FS_VLAN_DEPTH
];
418 u16 vlan_vid
[MLX5_FS_VLAN_DEPTH
];
419 u8 vlan_prio
[MLX5_FS_VLAN_DEPTH
];
423 struct mlx5_eswitch_rep
*rep
;
424 struct mlx5_pkt_reformat
*pkt_reformat
;
425 struct mlx5_core_dev
*mdev
;
426 struct mlx5_termtbl_handle
*termtbl
;
427 int src_port_rewrite_act_id
;
428 } dests
[MLX5_MAX_FLOW_FWD_VPORTS
];
429 struct mlx5_rx_tun_attr
*rx_tun_attr
;
430 struct mlx5_pkt_reformat
*decap_pkt_reformat
;
433 int mlx5_devlink_eswitch_mode_set(struct devlink
*devlink
, u16 mode
,
434 struct netlink_ext_ack
*extack
);
435 int mlx5_devlink_eswitch_mode_get(struct devlink
*devlink
, u16
*mode
);
436 int mlx5_devlink_eswitch_inline_mode_set(struct devlink
*devlink
, u8 mode
,
437 struct netlink_ext_ack
*extack
);
438 int mlx5_devlink_eswitch_inline_mode_get(struct devlink
*devlink
, u8
*mode
);
439 int mlx5_devlink_eswitch_encap_mode_set(struct devlink
*devlink
,
440 enum devlink_eswitch_encap_mode encap
,
441 struct netlink_ext_ack
*extack
);
442 int mlx5_devlink_eswitch_encap_mode_get(struct devlink
*devlink
,
443 enum devlink_eswitch_encap_mode
*encap
);
444 int mlx5_devlink_port_function_hw_addr_get(struct devlink
*devlink
,
445 struct devlink_port
*port
,
446 u8
*hw_addr
, int *hw_addr_len
,
447 struct netlink_ext_ack
*extack
);
448 int mlx5_devlink_port_function_hw_addr_set(struct devlink
*devlink
,
449 struct devlink_port
*port
,
450 const u8
*hw_addr
, int hw_addr_len
,
451 struct netlink_ext_ack
*extack
);
453 void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch
*esw
, u8 rep_type
);
455 int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch
*esw
,
456 struct mlx5_flow_attr
*attr
);
457 int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch
*esw
,
458 struct mlx5_flow_attr
*attr
);
459 int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch
*esw
,
460 u16 vport
, u16 vlan
, u8 qos
, u8 set_flags
);
462 static inline bool mlx5_esw_qos_enabled(struct mlx5_eswitch
*esw
)
464 return esw
->qos
.enabled
;
467 static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev
*dev
,
470 bool ret
= MLX5_CAP_ESW_FLOWTABLE_FDB(dev
, pop_vlan
) &&
471 MLX5_CAP_ESW_FLOWTABLE_FDB(dev
, push_vlan
);
476 return ret
&& MLX5_CAP_ESW_FLOWTABLE_FDB(dev
, pop_vlan_2
) &&
477 MLX5_CAP_ESW_FLOWTABLE_FDB(dev
, push_vlan_2
);
480 bool mlx5_esw_lag_prereq(struct mlx5_core_dev
*dev0
,
481 struct mlx5_core_dev
*dev1
);
482 bool mlx5_esw_multipath_prereq(struct mlx5_core_dev
*dev0
,
483 struct mlx5_core_dev
*dev1
);
485 const u32
*mlx5_esw_query_functions(struct mlx5_core_dev
*dev
);
487 #define MLX5_DEBUG_ESWITCH_MASK BIT(3)
489 #define esw_info(__dev, format, ...) \
490 dev_info((__dev)->device, "E-Switch: " format, ##__VA_ARGS__)
492 #define esw_warn(__dev, format, ...) \
493 dev_warn((__dev)->device, "E-Switch: " format, ##__VA_ARGS__)
495 #define esw_debug(dev, format, ...) \
496 mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
498 /* The returned number is valid only when the dev is eswitch manager. */
499 static inline u16
mlx5_eswitch_manager_vport(struct mlx5_core_dev
*dev
)
501 return mlx5_core_is_ecpf_esw_manager(dev
) ?
502 MLX5_VPORT_ECPF
: MLX5_VPORT_PF
;
506 mlx5_esw_is_manager_vport(const struct mlx5_eswitch
*esw
, u16 vport_num
)
508 return esw
->manager_vport
== vport_num
;
511 static inline u16
mlx5_eswitch_first_host_vport_num(struct mlx5_core_dev
*dev
)
513 return mlx5_core_is_ecpf_esw_manager(dev
) ?
514 MLX5_VPORT_PF
: MLX5_VPORT_FIRST_VF
;
517 static inline int mlx5_esw_sf_start_idx(const struct mlx5_eswitch
*esw
)
519 /* PF and VF vports indices start from 0 to max_vfs */
520 return MLX5_VPORT_PF_PLACEHOLDER
+ mlx5_core_max_vfs(esw
->dev
);
523 static inline int mlx5_esw_sf_end_idx(const struct mlx5_eswitch
*esw
)
525 return mlx5_esw_sf_start_idx(esw
) + mlx5_sf_max_functions(esw
->dev
);
529 mlx5_esw_sf_vport_num_to_index(const struct mlx5_eswitch
*esw
, u16 vport_num
)
531 return vport_num
- mlx5_sf_start_function_id(esw
->dev
) +
532 MLX5_VPORT_PF_PLACEHOLDER
+ mlx5_core_max_vfs(esw
->dev
);
536 mlx5_esw_sf_vport_index_to_num(const struct mlx5_eswitch
*esw
, int idx
)
538 return mlx5_sf_start_function_id(esw
->dev
) + idx
-
539 (MLX5_VPORT_PF_PLACEHOLDER
+ mlx5_core_max_vfs(esw
->dev
));
543 mlx5_esw_is_sf_vport(const struct mlx5_eswitch
*esw
, u16 vport_num
)
545 return mlx5_sf_supported(esw
->dev
) &&
546 vport_num
>= mlx5_sf_start_function_id(esw
->dev
) &&
547 (vport_num
< (mlx5_sf_start_function_id(esw
->dev
) +
548 mlx5_sf_max_functions(esw
->dev
)));
551 static inline bool mlx5_eswitch_is_funcs_handler(const struct mlx5_core_dev
*dev
)
553 return mlx5_core_is_ecpf_esw_manager(dev
);
556 static inline int mlx5_eswitch_uplink_idx(struct mlx5_eswitch
*esw
)
558 /* Uplink always locate at the last element of the array.*/
559 return esw
->total_vports
- 1;
562 static inline int mlx5_eswitch_ecpf_idx(struct mlx5_eswitch
*esw
)
564 return esw
->total_vports
- 2;
567 static inline int mlx5_eswitch_vport_num_to_index(struct mlx5_eswitch
*esw
,
570 if (vport_num
== MLX5_VPORT_ECPF
) {
571 if (!mlx5_ecpf_vport_exists(esw
->dev
))
572 esw_warn(esw
->dev
, "ECPF vport doesn't exist!\n");
573 return mlx5_eswitch_ecpf_idx(esw
);
576 if (vport_num
== MLX5_VPORT_UPLINK
)
577 return mlx5_eswitch_uplink_idx(esw
);
579 if (mlx5_esw_is_sf_vport(esw
, vport_num
))
580 return mlx5_esw_sf_vport_num_to_index(esw
, vport_num
);
582 /* PF and VF vports start from 0 to max_vfs */
586 static inline u16
mlx5_eswitch_index_to_vport_num(struct mlx5_eswitch
*esw
,
589 if (index
== mlx5_eswitch_ecpf_idx(esw
) &&
590 mlx5_ecpf_vport_exists(esw
->dev
))
591 return MLX5_VPORT_ECPF
;
593 if (index
== mlx5_eswitch_uplink_idx(esw
))
594 return MLX5_VPORT_UPLINK
;
596 /* SF vports indices are after VFs and before ECPF */
597 if (mlx5_sf_supported(esw
->dev
) &&
598 index
> mlx5_core_max_vfs(esw
->dev
))
599 return mlx5_esw_sf_vport_index_to_num(esw
, index
);
601 /* PF and VF vports start from 0 to max_vfs */
605 static inline unsigned int
606 mlx5_esw_vport_to_devlink_port_index(const struct mlx5_core_dev
*dev
,
609 return (MLX5_CAP_GEN(dev
, vhca_id
) << 16) | vport_num
;
613 mlx5_esw_devlink_port_index_to_vport_num(unsigned int dl_port_index
)
615 return dl_port_index
& 0xffff;
618 /* TODO: This mlx5e_tc function shouldn't be called by eswitch */
619 void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch
*esw
);
621 /* The vport getter/iterator are only valid after esw->total_vports
622 * and vport->vport are initialized in mlx5_eswitch_init.
624 #define mlx5_esw_for_all_vports(esw, i, vport) \
625 for ((i) = MLX5_VPORT_PF; \
626 (vport) = &(esw)->vports[i], \
627 (i) < (esw)->total_vports; (i)++)
629 #define mlx5_esw_for_all_vports_reverse(esw, i, vport) \
630 for ((i) = (esw)->total_vports - 1; \
631 (vport) = &(esw)->vports[i], \
632 (i) >= MLX5_VPORT_PF; (i)--)
634 #define mlx5_esw_for_each_vf_vport(esw, i, vport, nvfs) \
635 for ((i) = MLX5_VPORT_FIRST_VF; \
636 (vport) = &(esw)->vports[(i)], \
637 (i) <= (nvfs); (i)++)
639 #define mlx5_esw_for_each_vf_vport_reverse(esw, i, vport, nvfs) \
641 (vport) = &(esw)->vports[(i)], \
642 (i) >= MLX5_VPORT_FIRST_VF; (i)--)
644 /* The rep getter/iterator are only valid after esw->total_vports
645 * and vport->vport are initialized in mlx5_eswitch_init.
647 #define mlx5_esw_for_all_reps(esw, i, rep) \
648 for ((i) = MLX5_VPORT_PF; \
649 (rep) = &(esw)->offloads.vport_reps[i], \
650 (i) < (esw)->total_vports; (i)++)
652 #define mlx5_esw_for_each_vf_rep(esw, i, rep, nvfs) \
653 for ((i) = MLX5_VPORT_FIRST_VF; \
654 (rep) = &(esw)->offloads.vport_reps[i], \
655 (i) <= (nvfs); (i)++)
657 #define mlx5_esw_for_each_vf_rep_reverse(esw, i, rep, nvfs) \
659 (rep) = &(esw)->offloads.vport_reps[i], \
660 (i) >= MLX5_VPORT_FIRST_VF; (i)--)
662 #define mlx5_esw_for_each_vf_vport_num(esw, vport, nvfs) \
663 for ((vport) = MLX5_VPORT_FIRST_VF; (vport) <= (nvfs); (vport)++)
665 #define mlx5_esw_for_each_vf_vport_num_reverse(esw, vport, nvfs) \
666 for ((vport) = (nvfs); (vport) >= MLX5_VPORT_FIRST_VF; (vport)--)
668 /* Includes host PF (vport 0) if it's not esw manager. */
669 #define mlx5_esw_for_each_host_func_rep(esw, i, rep, nvfs) \
670 for ((i) = (esw)->first_host_vport; \
671 (rep) = &(esw)->offloads.vport_reps[i], \
672 (i) <= (nvfs); (i)++)
674 #define mlx5_esw_for_each_host_func_rep_reverse(esw, i, rep, nvfs) \
676 (rep) = &(esw)->offloads.vport_reps[i], \
677 (i) >= (esw)->first_host_vport; (i)--)
679 #define mlx5_esw_for_each_host_func_vport(esw, vport, nvfs) \
680 for ((vport) = (esw)->first_host_vport; \
681 (vport) <= (nvfs); (vport)++)
683 #define mlx5_esw_for_each_host_func_vport_reverse(esw, vport, nvfs) \
684 for ((vport) = (nvfs); \
685 (vport) >= (esw)->first_host_vport; (vport)--)
687 #define mlx5_esw_for_each_sf_rep(esw, i, rep) \
688 for ((i) = mlx5_esw_sf_start_idx(esw); \
689 (rep) = &(esw)->offloads.vport_reps[(i)], \
690 (i) < mlx5_esw_sf_end_idx(esw); (i++))
692 struct mlx5_eswitch
*mlx5_devlink_eswitch_get(struct devlink
*devlink
);
693 struct mlx5_vport
*__must_check
694 mlx5_eswitch_get_vport(struct mlx5_eswitch
*esw
, u16 vport_num
);
696 bool mlx5_eswitch_is_vf_vport(const struct mlx5_eswitch
*esw
, u16 vport_num
);
698 int mlx5_esw_funcs_changed_handler(struct notifier_block
*nb
, unsigned long type
, void *data
);
701 mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch
*esw
,
702 enum mlx5_eswitch_vport_event enabled_events
);
703 void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch
*esw
);
705 int mlx5_esw_vport_enable(struct mlx5_eswitch
*esw
, u16 vport_num
,
706 enum mlx5_eswitch_vport_event enabled_events
);
707 void mlx5_esw_vport_disable(struct mlx5_eswitch
*esw
, u16 vport_num
);
710 esw_vport_create_offloads_acl_tables(struct mlx5_eswitch
*esw
,
711 struct mlx5_vport
*vport
);
713 esw_vport_destroy_offloads_acl_tables(struct mlx5_eswitch
*esw
,
714 struct mlx5_vport
*vport
);
716 struct mlx5_vport_tbl_attr
{
722 struct mlx5_flow_table
*
723 mlx5_esw_vporttbl_get(struct mlx5_eswitch
*esw
, struct mlx5_vport_tbl_attr
*attr
);
725 mlx5_esw_vporttbl_put(struct mlx5_eswitch
*esw
, struct mlx5_vport_tbl_attr
*attr
);
727 struct mlx5_flow_handle
*
728 esw_add_restore_rule(struct mlx5_eswitch
*esw
, u32 tag
);
730 esw_get_max_restore_tag(struct mlx5_eswitch
*esw
);
732 int esw_offloads_load_rep(struct mlx5_eswitch
*esw
, u16 vport_num
);
733 void esw_offloads_unload_rep(struct mlx5_eswitch
*esw
, u16 vport_num
);
735 int mlx5_esw_offloads_rep_load(struct mlx5_eswitch
*esw
, u16 vport_num
);
736 void mlx5_esw_offloads_rep_unload(struct mlx5_eswitch
*esw
, u16 vport_num
);
738 int mlx5_eswitch_load_vport(struct mlx5_eswitch
*esw
, u16 vport_num
,
739 enum mlx5_eswitch_vport_event enabled_events
);
740 void mlx5_eswitch_unload_vport(struct mlx5_eswitch
*esw
, u16 vport_num
);
742 int mlx5_eswitch_load_vf_vports(struct mlx5_eswitch
*esw
, u16 num_vfs
,
743 enum mlx5_eswitch_vport_event enabled_events
);
744 void mlx5_eswitch_unload_vf_vports(struct mlx5_eswitch
*esw
, u16 num_vfs
);
746 int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch
*esw
, u16 vport_num
);
747 void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch
*esw
, u16 vport_num
);
748 struct devlink_port
*mlx5_esw_offloads_devlink_port(struct mlx5_eswitch
*esw
, u16 vport_num
);
750 int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch
*esw
, struct devlink_port
*dl_port
,
751 u16 vport_num
, u32 sfnum
);
752 void mlx5_esw_devlink_sf_port_unregister(struct mlx5_eswitch
*esw
, u16 vport_num
);
754 int mlx5_esw_offloads_sf_vport_enable(struct mlx5_eswitch
*esw
, struct devlink_port
*dl_port
,
755 u16 vport_num
, u32 sfnum
);
756 void mlx5_esw_offloads_sf_vport_disable(struct mlx5_eswitch
*esw
, u16 vport_num
);
758 int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch
*esw
, u16 vport_num
);
759 void mlx5_esw_vport_vhca_id_clear(struct mlx5_eswitch
*esw
, u16 vport_num
);
760 int mlx5_eswitch_vhca_id_to_vport(struct mlx5_eswitch
*esw
, u16 vhca_id
, u16
*vport_num
);
763 * mlx5_esw_event_info - Indicates eswitch mode changed/changing.
765 * @new_mode: New mode of eswitch.
767 struct mlx5_esw_event_info
{
771 int mlx5_esw_event_notifier_register(struct mlx5_eswitch
*esw
, struct notifier_block
*n
);
772 void mlx5_esw_event_notifier_unregister(struct mlx5_eswitch
*esw
, struct notifier_block
*n
);
774 bool mlx5_esw_hold(struct mlx5_core_dev
*dev
);
775 void mlx5_esw_release(struct mlx5_core_dev
*dev
);
776 void mlx5_esw_get(struct mlx5_core_dev
*dev
);
777 void mlx5_esw_put(struct mlx5_core_dev
*dev
);
778 int mlx5_esw_try_lock(struct mlx5_eswitch
*esw
);
779 void mlx5_esw_unlock(struct mlx5_eswitch
*esw
);
781 #else /* CONFIG_MLX5_ESWITCH */
782 /* eswitch API stubs */
783 static inline int mlx5_eswitch_init(struct mlx5_core_dev
*dev
) { return 0; }
784 static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch
*esw
) {}
785 static inline int mlx5_eswitch_enable(struct mlx5_eswitch
*esw
, int num_vfs
) { return 0; }
786 static inline void mlx5_eswitch_disable(struct mlx5_eswitch
*esw
, bool clear_vf
) {}
787 static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev
*dev0
, struct mlx5_core_dev
*dev1
) { return true; }
788 static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev
*dev
) { return false; }
790 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch
*esw
, u16 vport
, int link_state
) { return 0; }
791 static inline const u32
*mlx5_esw_query_functions(struct mlx5_core_dev
*dev
)
793 return ERR_PTR(-EOPNOTSUPP
);
796 static inline struct mlx5_flow_handle
*
797 esw_add_restore_rule(struct mlx5_eswitch
*esw
, u32 tag
)
799 return ERR_PTR(-EOPNOTSUPP
);
802 static inline unsigned int
803 mlx5_esw_vport_to_devlink_port_index(const struct mlx5_core_dev
*dev
,
808 #endif /* CONFIG_MLX5_ESWITCH */
810 #endif /* __MLX5_ESWITCH_H__ */