1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2019 Mellanox Technologies */
3 
4 #include <devlink.h>
5 
6 #include "mlx5_core.h"
7 #include "fw_reset.h"
8 #include "fs_core.h"
9 #include "eswitch.h"
10 #include "sf/dev/dev.h"
11 #include "sf/sf.h"
12 
13 static int mlx5_devlink_flash_update(struct devlink *devlink,
14 				     struct devlink_flash_update_params *params,
15 				     struct netlink_ext_ack *extack)
16 {
17 	struct mlx5_core_dev *dev = devlink_priv(devlink);
18 
19 	return mlx5_firmware_flash(dev, params->fw, extack);
20 }
21 
22 static u8 mlx5_fw_ver_major(u32 version)
23 {
24 	return (version >> 24) & 0xff;
25 }
26 
27 static u8 mlx5_fw_ver_minor(u32 version)
28 {
29 	return (version >> 16) & 0xff;
30 }
31 
32 static u16 mlx5_fw_ver_subminor(u32 version)
33 {
34 	return version & 0xffff;
35 }
36 
37 #define DEVLINK_FW_STRING_LEN 32
38 
39 static int
40 mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
41 		      struct netlink_ext_ack *extack)
42 {
43 	struct mlx5_core_dev *dev = devlink_priv(devlink);
44 	char version_str[DEVLINK_FW_STRING_LEN];
45 	u32 running_fw, stored_fw;
46 	int err;
47 
48 	err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
49 	if (err)
50 		return err;
51 
52 	err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
53 	if (err)
54 		return err;
55 
56 	err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
57 	if (err)
58 		return err;
59 
60 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
61 		 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
62 		 mlx5_fw_ver_subminor(running_fw));
63 	err = devlink_info_version_running_put(req, "fw.version", version_str);
64 	if (err)
65 		return err;
66 	err = devlink_info_version_running_put(req,
67 					       DEVLINK_INFO_VERSION_GENERIC_FW,
68 					       version_str);
69 	if (err)
70 		return err;
71 
72 	/* no pending version, return running (stored) version */
73 	if (stored_fw == 0)
74 		stored_fw = running_fw;
75 
76 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
77 		 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
78 		 mlx5_fw_ver_subminor(stored_fw));
79 	err = devlink_info_version_stored_put(req, "fw.version", version_str);
80 	if (err)
81 		return err;
82 	return devlink_info_version_stored_put(req,
83 					       DEVLINK_INFO_VERSION_GENERIC_FW,
84 					       version_str);
85 }
86 
87 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
88 {
89 	struct mlx5_core_dev *dev = devlink_priv(devlink);
90 	u8 reset_level, reset_type, net_port_alive;
91 	int err;
92 
93 	err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
94 	if (err)
95 		return err;
96 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
97 		NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
98 		return -EINVAL;
99 	}
100 
101 	net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
102 	err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive);
103 	if (err)
104 		goto out;
105 
106 	err = mlx5_fw_reset_wait_reset_done(dev);
107 out:
108 	if (err)
109 		NL_SET_ERR_MSG_MOD(extack, "FW activate command failed");
110 	return err;
111 }
112 
113 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
114 					      struct netlink_ext_ack *extack)
115 {
116 	struct mlx5_core_dev *dev = devlink_priv(devlink);
117 	u8 reset_level;
118 	int err;
119 
120 	err = mlx5_fw_reset_query(dev, &reset_level, NULL);
121 	if (err)
122 		return err;
123 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
124 		NL_SET_ERR_MSG_MOD(extack,
125 				   "FW upgrade to the stored FW can't be done by FW live patching");
126 		return -EINVAL;
127 	}
128 
129 	return mlx5_fw_reset_set_live_patch(dev);
130 }
131 
132 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
133 				    enum devlink_reload_action action,
134 				    enum devlink_reload_limit limit,
135 				    struct netlink_ext_ack *extack)
136 {
137 	struct mlx5_core_dev *dev = devlink_priv(devlink);
138 	bool sf_dev_allocated;
139 
140 	sf_dev_allocated = mlx5_sf_dev_allocated(dev);
141 	if (sf_dev_allocated) {
142 		/* Reload results in deleting SF device which further results in
143 		 * unregistering devlink instance while holding devlink_mutext.
144 		 * Hence, do not support reload.
145 		 */
146 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
147 		return -EOPNOTSUPP;
148 	}
149 
150 	if (mlx5_lag_is_active(dev)) {
151 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
152 		return -EOPNOTSUPP;
153 	}
154 
155 	switch (action) {
156 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
157 		mlx5_unload_one(dev);
158 		return 0;
159 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
160 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
161 			return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
162 		return mlx5_devlink_reload_fw_activate(devlink, extack);
163 	default:
164 		/* Unsupported action should not get to this function */
165 		WARN_ON(1);
166 		return -EOPNOTSUPP;
167 	}
168 }
169 
170 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
171 				  enum devlink_reload_limit limit, u32 *actions_performed,
172 				  struct netlink_ext_ack *extack)
173 {
174 	struct mlx5_core_dev *dev = devlink_priv(devlink);
175 
176 	*actions_performed = BIT(action);
177 	switch (action) {
178 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
179 		return mlx5_load_one(dev);
180 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
181 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
182 			break;
183 		/* On fw_activate action, also driver is reloaded and reinit performed */
184 		*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
185 		return mlx5_load_one(dev);
186 	default:
187 		/* Unsupported action should not get to this function */
188 		WARN_ON(1);
189 		return -EOPNOTSUPP;
190 	}
191 
192 	return 0;
193 }
194 
195 static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
196 {
197 	struct mlx5_devlink_trap *dl_trap;
198 
199 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
200 		if (dl_trap->trap.id == trap_id)
201 			return dl_trap;
202 
203 	return NULL;
204 }
205 
206 static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
207 				  void *trap_ctx)
208 {
209 	struct mlx5_core_dev *dev = devlink_priv(devlink);
210 	struct mlx5_devlink_trap *dl_trap;
211 
212 	dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
213 	if (!dl_trap)
214 		return -ENOMEM;
215 
216 	dl_trap->trap.id = trap->id;
217 	dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
218 	dl_trap->item = trap_ctx;
219 
220 	if (mlx5_find_trap_by_id(dev, trap->id)) {
221 		kfree(dl_trap);
222 		mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
223 		return -EEXIST;
224 	}
225 
226 	list_add_tail(&dl_trap->list, &dev->priv.traps);
227 	return 0;
228 }
229 
230 static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
231 				   void *trap_ctx)
232 {
233 	struct mlx5_core_dev *dev = devlink_priv(devlink);
234 	struct mlx5_devlink_trap *dl_trap;
235 
236 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
237 	if (!dl_trap) {
238 		mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
239 		return;
240 	}
241 	list_del(&dl_trap->list);
242 	kfree(dl_trap);
243 }
244 
245 static int mlx5_devlink_trap_action_set(struct devlink *devlink,
246 					const struct devlink_trap *trap,
247 					enum devlink_trap_action action,
248 					struct netlink_ext_ack *extack)
249 {
250 	struct mlx5_core_dev *dev = devlink_priv(devlink);
251 	enum devlink_trap_action action_orig;
252 	struct mlx5_devlink_trap *dl_trap;
253 	int err = 0;
254 
255 	if (is_mdev_switchdev_mode(dev)) {
256 		NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
257 		return -EOPNOTSUPP;
258 	}
259 
260 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
261 	if (!dl_trap) {
262 		mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
263 		err = -EINVAL;
264 		goto out;
265 	}
266 
267 	if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
268 		err = -EOPNOTSUPP;
269 		goto out;
270 	}
271 
272 	if (action == dl_trap->trap.action)
273 		goto out;
274 
275 	action_orig = dl_trap->trap.action;
276 	dl_trap->trap.action = action;
277 	err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
278 						&dl_trap->trap);
279 	if (err)
280 		dl_trap->trap.action = action_orig;
281 out:
282 	return err;
283 }
284 
285 static const struct devlink_ops mlx5_devlink_ops = {
286 #ifdef CONFIG_MLX5_ESWITCH
287 	.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
288 	.eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
289 	.eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
290 	.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
291 	.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
292 	.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
293 	.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
294 	.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
295 #endif
296 #ifdef CONFIG_MLX5_SF_MANAGER
297 	.port_new = mlx5_devlink_sf_port_new,
298 	.port_del = mlx5_devlink_sf_port_del,
299 	.port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
300 	.port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
301 #endif
302 	.flash_update = mlx5_devlink_flash_update,
303 	.info_get = mlx5_devlink_info_get,
304 	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
305 			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
306 	.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
307 	.reload_down = mlx5_devlink_reload_down,
308 	.reload_up = mlx5_devlink_reload_up,
309 	.trap_init = mlx5_devlink_trap_init,
310 	.trap_fini = mlx5_devlink_trap_fini,
311 	.trap_action_set = mlx5_devlink_trap_action_set,
312 };
313 
314 void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
315 			      struct devlink_port *dl_port)
316 {
317 	struct devlink *devlink = priv_to_devlink(dev);
318 	struct mlx5_devlink_trap *dl_trap;
319 
320 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
321 	if (!dl_trap) {
322 		mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
323 		return;
324 	}
325 
326 	if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
327 		mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
328 			      dl_trap->trap.action);
329 		return;
330 	}
331 	devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
332 }
333 
334 int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
335 {
336 	struct mlx5_devlink_trap *dl_trap;
337 	int count = 0;
338 
339 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
340 		if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
341 			count++;
342 
343 	return count;
344 }
345 
346 int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
347 				  enum devlink_trap_action *action)
348 {
349 	struct mlx5_devlink_trap *dl_trap;
350 
351 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
352 	if (!dl_trap) {
353 		mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
354 			      trap_id);
355 		return -EINVAL;
356 	}
357 
358 	*action = dl_trap->trap.action;
359 	return 0;
360 }
361 
362 struct devlink *mlx5_devlink_alloc(void)
363 {
364 	return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev));
365 }
366 
367 void mlx5_devlink_free(struct devlink *devlink)
368 {
369 	devlink_free(devlink);
370 }
371 
372 static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
373 					 union devlink_param_value val,
374 					 struct netlink_ext_ack *extack)
375 {
376 	struct mlx5_core_dev *dev = devlink_priv(devlink);
377 	char *value = val.vstr;
378 	int err = 0;
379 
380 	if (!strcmp(value, "dmfs")) {
381 		return 0;
382 	} else if (!strcmp(value, "smfs")) {
383 		u8 eswitch_mode;
384 		bool smfs_cap;
385 
386 		eswitch_mode = mlx5_eswitch_mode(dev);
387 		smfs_cap = mlx5_fs_dr_is_supported(dev);
388 
389 		if (!smfs_cap) {
390 			err = -EOPNOTSUPP;
391 			NL_SET_ERR_MSG_MOD(extack,
392 					   "Software managed steering is not supported by current device");
393 		}
394 
395 		else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
396 			NL_SET_ERR_MSG_MOD(extack,
397 					   "Software managed steering is not supported when eswitch offloads enabled.");
398 			err = -EOPNOTSUPP;
399 		}
400 	} else {
401 		NL_SET_ERR_MSG_MOD(extack,
402 				   "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
403 		err = -EINVAL;
404 	}
405 
406 	return err;
407 }
408 
409 static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
410 				    struct devlink_param_gset_ctx *ctx)
411 {
412 	struct mlx5_core_dev *dev = devlink_priv(devlink);
413 	enum mlx5_flow_steering_mode mode;
414 
415 	if (!strcmp(ctx->val.vstr, "smfs"))
416 		mode = MLX5_FLOW_STEERING_MODE_SMFS;
417 	else
418 		mode = MLX5_FLOW_STEERING_MODE_DMFS;
419 	dev->priv.steering->mode = mode;
420 
421 	return 0;
422 }
423 
424 static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
425 				    struct devlink_param_gset_ctx *ctx)
426 {
427 	struct mlx5_core_dev *dev = devlink_priv(devlink);
428 
429 	if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
430 		strcpy(ctx->val.vstr, "smfs");
431 	else
432 		strcpy(ctx->val.vstr, "dmfs");
433 	return 0;
434 }
435 
436 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
437 					     union devlink_param_value val,
438 					     struct netlink_ext_ack *extack)
439 {
440 	struct mlx5_core_dev *dev = devlink_priv(devlink);
441 	bool new_state = val.vbool;
442 
443 	if (new_state && !MLX5_CAP_GEN(dev, roce)) {
444 		NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
445 		return -EOPNOTSUPP;
446 	}
447 	if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
448 		NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
449 		return -EOPNOTSUPP;
450 	}
451 
452 	return 0;
453 }
454 
455 #ifdef CONFIG_MLX5_ESWITCH
456 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
457 						 union devlink_param_value val,
458 						 struct netlink_ext_ack *extack)
459 {
460 	int group_num = val.vu32;
461 
462 	if (group_num < 1 || group_num > 1024) {
463 		NL_SET_ERR_MSG_MOD(extack,
464 				   "Unsupported group number, supported range is 1-1024");
465 		return -EOPNOTSUPP;
466 	}
467 
468 	return 0;
469 }
470 
471 static int mlx5_devlink_esw_port_metadata_set(struct devlink *devlink, u32 id,
472 					      struct devlink_param_gset_ctx *ctx)
473 {
474 	struct mlx5_core_dev *dev = devlink_priv(devlink);
475 
476 	if (!MLX5_ESWITCH_MANAGER(dev))
477 		return -EOPNOTSUPP;
478 
479 	return mlx5_esw_offloads_vport_metadata_set(dev->priv.eswitch, ctx->val.vbool);
480 }
481 
482 static int mlx5_devlink_esw_port_metadata_get(struct devlink *devlink, u32 id,
483 					      struct devlink_param_gset_ctx *ctx)
484 {
485 	struct mlx5_core_dev *dev = devlink_priv(devlink);
486 
487 	if (!MLX5_ESWITCH_MANAGER(dev))
488 		return -EOPNOTSUPP;
489 
490 	ctx->val.vbool = mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch);
491 	return 0;
492 }
493 
494 static int mlx5_devlink_esw_port_metadata_validate(struct devlink *devlink, u32 id,
495 						   union devlink_param_value val,
496 						   struct netlink_ext_ack *extack)
497 {
498 	struct mlx5_core_dev *dev = devlink_priv(devlink);
499 	u8 esw_mode;
500 
501 	if (!MLX5_ESWITCH_MANAGER(dev)) {
502 		NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported");
503 		return -EOPNOTSUPP;
504 	}
505 	esw_mode = mlx5_eswitch_mode(dev);
506 	if (esw_mode == MLX5_ESWITCH_OFFLOADS) {
507 		NL_SET_ERR_MSG_MOD(extack,
508 				   "E-Switch must either disabled or non switchdev mode");
509 		return -EBUSY;
510 	}
511 	return 0;
512 }
513 
514 #endif
515 
516 static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
517 						    struct devlink_param_gset_ctx *ctx)
518 {
519 	struct mlx5_core_dev *dev = devlink_priv(devlink);
520 
521 	mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool);
522 	return 0;
523 }
524 
525 static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
526 						    struct devlink_param_gset_ctx *ctx)
527 {
528 	struct mlx5_core_dev *dev = devlink_priv(devlink);
529 
530 	ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev);
531 	return 0;
532 }
533 
534 static const struct devlink_param mlx5_devlink_params[] = {
535 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
536 			     "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
537 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
538 			     mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
539 			     mlx5_devlink_fs_mode_validate),
540 	DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
541 			      NULL, NULL, mlx5_devlink_enable_roce_validate),
542 #ifdef CONFIG_MLX5_ESWITCH
543 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
544 			     "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
545 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
546 			     NULL, NULL,
547 			     mlx5_devlink_large_group_num_validate),
548 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
549 			     "esw_port_metadata", DEVLINK_PARAM_TYPE_BOOL,
550 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
551 			     mlx5_devlink_esw_port_metadata_get,
552 			     mlx5_devlink_esw_port_metadata_set,
553 			     mlx5_devlink_esw_port_metadata_validate),
554 #endif
555 	DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
556 			      mlx5_devlink_enable_remote_dev_reset_get,
557 			      mlx5_devlink_enable_remote_dev_reset_set, NULL),
558 };
559 
560 static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
561 {
562 	struct mlx5_core_dev *dev = devlink_priv(devlink);
563 	union devlink_param_value value;
564 
565 	if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS)
566 		strcpy(value.vstr, "dmfs");
567 	else
568 		strcpy(value.vstr, "smfs");
569 	devlink_param_driverinit_value_set(devlink,
570 					   MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
571 					   value);
572 
573 	value.vbool = MLX5_CAP_GEN(dev, roce);
574 	devlink_param_driverinit_value_set(devlink,
575 					   DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
576 					   value);
577 
578 #ifdef CONFIG_MLX5_ESWITCH
579 	value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
580 	devlink_param_driverinit_value_set(devlink,
581 					   MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
582 					   value);
583 
584 	if (MLX5_ESWITCH_MANAGER(dev)) {
585 		if (mlx5_esw_vport_match_metadata_supported(dev->priv.eswitch)) {
586 			dev->priv.eswitch->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
587 			value.vbool = true;
588 		} else {
589 			value.vbool = false;
590 		}
591 		devlink_param_driverinit_value_set(devlink,
592 						   MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
593 						   value);
594 	}
595 #endif
596 }
597 
598 #define MLX5_TRAP_DROP(_id, _group_id)					\
599 	DEVLINK_TRAP_GENERIC(DROP, DROP, _id,				\
600 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
601 			     DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
602 
603 static const struct devlink_trap mlx5_traps_arr[] = {
604 	MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
605 	MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
606 };
607 
608 static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
609 	DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
610 };
611 
612 static int mlx5_devlink_traps_register(struct devlink *devlink)
613 {
614 	struct mlx5_core_dev *core_dev = devlink_priv(devlink);
615 	int err;
616 
617 	err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr,
618 					   ARRAY_SIZE(mlx5_trap_groups_arr));
619 	if (err)
620 		return err;
621 
622 	err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
623 				     &core_dev->priv);
624 	if (err)
625 		goto err_trap_group;
626 	return 0;
627 
628 err_trap_group:
629 	devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
630 				       ARRAY_SIZE(mlx5_trap_groups_arr));
631 	return err;
632 }
633 
634 static void mlx5_devlink_traps_unregister(struct devlink *devlink)
635 {
636 	devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
637 	devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
638 				       ARRAY_SIZE(mlx5_trap_groups_arr));
639 }
640 
641 int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
642 {
643 	int err;
644 
645 	err = devlink_register(devlink, dev);
646 	if (err)
647 		return err;
648 
649 	err = devlink_params_register(devlink, mlx5_devlink_params,
650 				      ARRAY_SIZE(mlx5_devlink_params));
651 	if (err)
652 		goto params_reg_err;
653 	mlx5_devlink_set_params_init_values(devlink);
654 	devlink_params_publish(devlink);
655 
656 	err = mlx5_devlink_traps_register(devlink);
657 	if (err)
658 		goto traps_reg_err;
659 
660 	return 0;
661 
662 traps_reg_err:
663 	devlink_params_unregister(devlink, mlx5_devlink_params,
664 				  ARRAY_SIZE(mlx5_devlink_params));
665 params_reg_err:
666 	devlink_unregister(devlink);
667 	return err;
668 }
669 
670 void mlx5_devlink_unregister(struct devlink *devlink)
671 {
672 	mlx5_devlink_traps_unregister(devlink);
673 	devlink_params_unregister(devlink, mlx5_devlink_params,
674 				  ARRAY_SIZE(mlx5_devlink_params));
675 	devlink_unregister(devlink);
676 }
677