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 "esw/qos.h"
11 #include "sf/dev/dev.h"
12 #include "sf/sf.h"
13 
14 static int mlx5_devlink_flash_update(struct devlink *devlink,
15 				     struct devlink_flash_update_params *params,
16 				     struct netlink_ext_ack *extack)
17 {
18 	struct mlx5_core_dev *dev = devlink_priv(devlink);
19 
20 	return mlx5_firmware_flash(dev, params->fw, extack);
21 }
22 
23 static u8 mlx5_fw_ver_major(u32 version)
24 {
25 	return (version >> 24) & 0xff;
26 }
27 
28 static u8 mlx5_fw_ver_minor(u32 version)
29 {
30 	return (version >> 16) & 0xff;
31 }
32 
33 static u16 mlx5_fw_ver_subminor(u32 version)
34 {
35 	return version & 0xffff;
36 }
37 
38 #define DEVLINK_FW_STRING_LEN 32
39 
40 static int
41 mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
42 		      struct netlink_ext_ack *extack)
43 {
44 	struct mlx5_core_dev *dev = devlink_priv(devlink);
45 	char version_str[DEVLINK_FW_STRING_LEN];
46 	u32 running_fw, stored_fw;
47 	int err;
48 
49 	err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
50 	if (err)
51 		return err;
52 
53 	err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
54 	if (err)
55 		return err;
56 
57 	err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
58 	if (err)
59 		return err;
60 
61 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
62 		 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
63 		 mlx5_fw_ver_subminor(running_fw));
64 	err = devlink_info_version_running_put(req, "fw.version", version_str);
65 	if (err)
66 		return err;
67 	err = devlink_info_version_running_put(req,
68 					       DEVLINK_INFO_VERSION_GENERIC_FW,
69 					       version_str);
70 	if (err)
71 		return err;
72 
73 	/* no pending version, return running (stored) version */
74 	if (stored_fw == 0)
75 		stored_fw = running_fw;
76 
77 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
78 		 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
79 		 mlx5_fw_ver_subminor(stored_fw));
80 	err = devlink_info_version_stored_put(req, "fw.version", version_str);
81 	if (err)
82 		return err;
83 	return devlink_info_version_stored_put(req,
84 					       DEVLINK_INFO_VERSION_GENERIC_FW,
85 					       version_str);
86 }
87 
88 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
89 {
90 	struct mlx5_core_dev *dev = devlink_priv(devlink);
91 	u8 reset_level, reset_type, net_port_alive;
92 	int err;
93 
94 	err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
95 	if (err)
96 		return err;
97 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
98 		NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
99 		return -EINVAL;
100 	}
101 
102 	net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
103 	err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive, extack);
104 	if (err)
105 		return err;
106 
107 	return mlx5_fw_reset_wait_reset_done(dev);
108 }
109 
110 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
111 					      struct netlink_ext_ack *extack)
112 {
113 	struct mlx5_core_dev *dev = devlink_priv(devlink);
114 	u8 reset_level;
115 	int err;
116 
117 	err = mlx5_fw_reset_query(dev, &reset_level, NULL);
118 	if (err)
119 		return err;
120 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
121 		NL_SET_ERR_MSG_MOD(extack,
122 				   "FW upgrade to the stored FW can't be done by FW live patching");
123 		return -EINVAL;
124 	}
125 
126 	return mlx5_fw_reset_set_live_patch(dev);
127 }
128 
129 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
130 				    enum devlink_reload_action action,
131 				    enum devlink_reload_limit limit,
132 				    struct netlink_ext_ack *extack)
133 {
134 	struct mlx5_core_dev *dev = devlink_priv(devlink);
135 	struct pci_dev *pdev = dev->pdev;
136 	bool sf_dev_allocated;
137 
138 	sf_dev_allocated = mlx5_sf_dev_allocated(dev);
139 	if (sf_dev_allocated) {
140 		/* Reload results in deleting SF device which further results in
141 		 * unregistering devlink instance while holding devlink_mutext.
142 		 * Hence, do not support reload.
143 		 */
144 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
145 		return -EOPNOTSUPP;
146 	}
147 
148 	if (mlx5_lag_is_active(dev)) {
149 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
150 		return -EOPNOTSUPP;
151 	}
152 
153 	if (pci_num_vf(pdev)) {
154 		NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
155 	}
156 
157 	switch (action) {
158 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
159 		mlx5_unload_one(dev);
160 		return 0;
161 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
162 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
163 			return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
164 		return mlx5_devlink_reload_fw_activate(devlink, extack);
165 	default:
166 		/* Unsupported action should not get to this function */
167 		WARN_ON(1);
168 		return -EOPNOTSUPP;
169 	}
170 }
171 
172 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
173 				  enum devlink_reload_limit limit, u32 *actions_performed,
174 				  struct netlink_ext_ack *extack)
175 {
176 	struct mlx5_core_dev *dev = devlink_priv(devlink);
177 
178 	*actions_performed = BIT(action);
179 	switch (action) {
180 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
181 		return mlx5_load_one(dev);
182 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
183 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
184 			break;
185 		/* On fw_activate action, also driver is reloaded and reinit performed */
186 		*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
187 		return mlx5_load_one(dev);
188 	default:
189 		/* Unsupported action should not get to this function */
190 		WARN_ON(1);
191 		return -EOPNOTSUPP;
192 	}
193 
194 	return 0;
195 }
196 
197 static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
198 {
199 	struct mlx5_devlink_trap *dl_trap;
200 
201 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
202 		if (dl_trap->trap.id == trap_id)
203 			return dl_trap;
204 
205 	return NULL;
206 }
207 
208 static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
209 				  void *trap_ctx)
210 {
211 	struct mlx5_core_dev *dev = devlink_priv(devlink);
212 	struct mlx5_devlink_trap *dl_trap;
213 
214 	dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
215 	if (!dl_trap)
216 		return -ENOMEM;
217 
218 	dl_trap->trap.id = trap->id;
219 	dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
220 	dl_trap->item = trap_ctx;
221 
222 	if (mlx5_find_trap_by_id(dev, trap->id)) {
223 		kfree(dl_trap);
224 		mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
225 		return -EEXIST;
226 	}
227 
228 	list_add_tail(&dl_trap->list, &dev->priv.traps);
229 	return 0;
230 }
231 
232 static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
233 				   void *trap_ctx)
234 {
235 	struct mlx5_core_dev *dev = devlink_priv(devlink);
236 	struct mlx5_devlink_trap *dl_trap;
237 
238 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
239 	if (!dl_trap) {
240 		mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
241 		return;
242 	}
243 	list_del(&dl_trap->list);
244 	kfree(dl_trap);
245 }
246 
247 static int mlx5_devlink_trap_action_set(struct devlink *devlink,
248 					const struct devlink_trap *trap,
249 					enum devlink_trap_action action,
250 					struct netlink_ext_ack *extack)
251 {
252 	struct mlx5_core_dev *dev = devlink_priv(devlink);
253 	enum devlink_trap_action action_orig;
254 	struct mlx5_devlink_trap *dl_trap;
255 	int err = 0;
256 
257 	if (is_mdev_switchdev_mode(dev)) {
258 		NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
259 		return -EOPNOTSUPP;
260 	}
261 
262 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
263 	if (!dl_trap) {
264 		mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
265 		err = -EINVAL;
266 		goto out;
267 	}
268 
269 	if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
270 		err = -EOPNOTSUPP;
271 		goto out;
272 	}
273 
274 	if (action == dl_trap->trap.action)
275 		goto out;
276 
277 	action_orig = dl_trap->trap.action;
278 	dl_trap->trap.action = action;
279 	err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
280 						&dl_trap->trap);
281 	if (err)
282 		dl_trap->trap.action = action_orig;
283 out:
284 	return err;
285 }
286 
287 static const struct devlink_ops mlx5_devlink_ops = {
288 #ifdef CONFIG_MLX5_ESWITCH
289 	.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
290 	.eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
291 	.eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
292 	.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
293 	.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
294 	.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
295 	.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
296 	.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
297 	.rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
298 	.rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
299 	.rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
300 	.rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
301 	.rate_node_new = mlx5_esw_devlink_rate_node_new,
302 	.rate_node_del = mlx5_esw_devlink_rate_node_del,
303 	.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
304 #endif
305 #ifdef CONFIG_MLX5_SF_MANAGER
306 	.port_new = mlx5_devlink_sf_port_new,
307 	.port_del = mlx5_devlink_sf_port_del,
308 	.port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
309 	.port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
310 #endif
311 	.flash_update = mlx5_devlink_flash_update,
312 	.info_get = mlx5_devlink_info_get,
313 	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
314 			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
315 	.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
316 	.reload_down = mlx5_devlink_reload_down,
317 	.reload_up = mlx5_devlink_reload_up,
318 	.trap_init = mlx5_devlink_trap_init,
319 	.trap_fini = mlx5_devlink_trap_fini,
320 	.trap_action_set = mlx5_devlink_trap_action_set,
321 };
322 
323 void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
324 			      struct devlink_port *dl_port)
325 {
326 	struct devlink *devlink = priv_to_devlink(dev);
327 	struct mlx5_devlink_trap *dl_trap;
328 
329 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
330 	if (!dl_trap) {
331 		mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
332 		return;
333 	}
334 
335 	if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
336 		mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
337 			      dl_trap->trap.action);
338 		return;
339 	}
340 	devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
341 }
342 
343 int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
344 {
345 	struct mlx5_devlink_trap *dl_trap;
346 	int count = 0;
347 
348 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
349 		if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
350 			count++;
351 
352 	return count;
353 }
354 
355 int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
356 				  enum devlink_trap_action *action)
357 {
358 	struct mlx5_devlink_trap *dl_trap;
359 
360 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
361 	if (!dl_trap) {
362 		mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
363 			      trap_id);
364 		return -EINVAL;
365 	}
366 
367 	*action = dl_trap->trap.action;
368 	return 0;
369 }
370 
371 struct devlink *mlx5_devlink_alloc(struct device *dev)
372 {
373 	return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
374 			     dev);
375 }
376 
377 void mlx5_devlink_free(struct devlink *devlink)
378 {
379 	devlink_free(devlink);
380 }
381 
382 static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
383 					 union devlink_param_value val,
384 					 struct netlink_ext_ack *extack)
385 {
386 	struct mlx5_core_dev *dev = devlink_priv(devlink);
387 	char *value = val.vstr;
388 	int err = 0;
389 
390 	if (!strcmp(value, "dmfs")) {
391 		return 0;
392 	} else if (!strcmp(value, "smfs")) {
393 		u8 eswitch_mode;
394 		bool smfs_cap;
395 
396 		eswitch_mode = mlx5_eswitch_mode(dev);
397 		smfs_cap = mlx5_fs_dr_is_supported(dev);
398 
399 		if (!smfs_cap) {
400 			err = -EOPNOTSUPP;
401 			NL_SET_ERR_MSG_MOD(extack,
402 					   "Software managed steering is not supported by current device");
403 		}
404 
405 		else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
406 			NL_SET_ERR_MSG_MOD(extack,
407 					   "Software managed steering is not supported when eswitch offloads enabled.");
408 			err = -EOPNOTSUPP;
409 		}
410 	} else {
411 		NL_SET_ERR_MSG_MOD(extack,
412 				   "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
413 		err = -EINVAL;
414 	}
415 
416 	return err;
417 }
418 
419 static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
420 				    struct devlink_param_gset_ctx *ctx)
421 {
422 	struct mlx5_core_dev *dev = devlink_priv(devlink);
423 	enum mlx5_flow_steering_mode mode;
424 
425 	if (!strcmp(ctx->val.vstr, "smfs"))
426 		mode = MLX5_FLOW_STEERING_MODE_SMFS;
427 	else
428 		mode = MLX5_FLOW_STEERING_MODE_DMFS;
429 	dev->priv.steering->mode = mode;
430 
431 	return 0;
432 }
433 
434 static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
435 				    struct devlink_param_gset_ctx *ctx)
436 {
437 	struct mlx5_core_dev *dev = devlink_priv(devlink);
438 
439 	if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
440 		strcpy(ctx->val.vstr, "smfs");
441 	else
442 		strcpy(ctx->val.vstr, "dmfs");
443 	return 0;
444 }
445 
446 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
447 					     union devlink_param_value val,
448 					     struct netlink_ext_ack *extack)
449 {
450 	struct mlx5_core_dev *dev = devlink_priv(devlink);
451 	bool new_state = val.vbool;
452 
453 	if (new_state && !MLX5_CAP_GEN(dev, roce) &&
454 	    !MLX5_CAP_GEN(dev, roce_rw_supported)) {
455 		NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
456 		return -EOPNOTSUPP;
457 	}
458 	if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
459 		NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
460 		return -EOPNOTSUPP;
461 	}
462 
463 	return 0;
464 }
465 
466 #ifdef CONFIG_MLX5_ESWITCH
467 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
468 						 union devlink_param_value val,
469 						 struct netlink_ext_ack *extack)
470 {
471 	int group_num = val.vu32;
472 
473 	if (group_num < 1 || group_num > 1024) {
474 		NL_SET_ERR_MSG_MOD(extack,
475 				   "Unsupported group number, supported range is 1-1024");
476 		return -EOPNOTSUPP;
477 	}
478 
479 	return 0;
480 }
481 
482 static int mlx5_devlink_esw_port_metadata_set(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 	return mlx5_esw_offloads_vport_metadata_set(dev->priv.eswitch, ctx->val.vbool);
491 }
492 
493 static int mlx5_devlink_esw_port_metadata_get(struct devlink *devlink, u32 id,
494 					      struct devlink_param_gset_ctx *ctx)
495 {
496 	struct mlx5_core_dev *dev = devlink_priv(devlink);
497 
498 	if (!MLX5_ESWITCH_MANAGER(dev))
499 		return -EOPNOTSUPP;
500 
501 	ctx->val.vbool = mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch);
502 	return 0;
503 }
504 
505 static int mlx5_devlink_esw_port_metadata_validate(struct devlink *devlink, u32 id,
506 						   union devlink_param_value val,
507 						   struct netlink_ext_ack *extack)
508 {
509 	struct mlx5_core_dev *dev = devlink_priv(devlink);
510 	u8 esw_mode;
511 
512 	if (!MLX5_ESWITCH_MANAGER(dev)) {
513 		NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported");
514 		return -EOPNOTSUPP;
515 	}
516 	esw_mode = mlx5_eswitch_mode(dev);
517 	if (esw_mode == MLX5_ESWITCH_OFFLOADS) {
518 		NL_SET_ERR_MSG_MOD(extack,
519 				   "E-Switch must either disabled or non switchdev mode");
520 		return -EBUSY;
521 	}
522 	return 0;
523 }
524 
525 #endif
526 
527 static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
528 						    struct devlink_param_gset_ctx *ctx)
529 {
530 	struct mlx5_core_dev *dev = devlink_priv(devlink);
531 
532 	mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool);
533 	return 0;
534 }
535 
536 static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
537 						    struct devlink_param_gset_ctx *ctx)
538 {
539 	struct mlx5_core_dev *dev = devlink_priv(devlink);
540 
541 	ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev);
542 	return 0;
543 }
544 
545 static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
546 					  union devlink_param_value val,
547 					  struct netlink_ext_ack *extack)
548 {
549 	return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
550 }
551 
552 static const struct devlink_param mlx5_devlink_params[] = {
553 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
554 			     "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
555 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
556 			     mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
557 			     mlx5_devlink_fs_mode_validate),
558 	DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
559 			      NULL, NULL, mlx5_devlink_enable_roce_validate),
560 #ifdef CONFIG_MLX5_ESWITCH
561 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
562 			     "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
563 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
564 			     NULL, NULL,
565 			     mlx5_devlink_large_group_num_validate),
566 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
567 			     "esw_port_metadata", DEVLINK_PARAM_TYPE_BOOL,
568 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
569 			     mlx5_devlink_esw_port_metadata_get,
570 			     mlx5_devlink_esw_port_metadata_set,
571 			     mlx5_devlink_esw_port_metadata_validate),
572 #endif
573 	DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
574 			      mlx5_devlink_enable_remote_dev_reset_get,
575 			      mlx5_devlink_enable_remote_dev_reset_set, NULL),
576 	DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
577 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
578 	DEVLINK_PARAM_GENERIC(EVENT_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
579 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
580 };
581 
582 static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
583 {
584 	struct mlx5_core_dev *dev = devlink_priv(devlink);
585 	union devlink_param_value value;
586 
587 	if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS)
588 		strcpy(value.vstr, "dmfs");
589 	else
590 		strcpy(value.vstr, "smfs");
591 	devlink_param_driverinit_value_set(devlink,
592 					   MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
593 					   value);
594 
595 	value.vbool = MLX5_CAP_GEN(dev, roce);
596 	devlink_param_driverinit_value_set(devlink,
597 					   DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
598 					   value);
599 
600 #ifdef CONFIG_MLX5_ESWITCH
601 	value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
602 	devlink_param_driverinit_value_set(devlink,
603 					   MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
604 					   value);
605 
606 	if (MLX5_ESWITCH_MANAGER(dev)) {
607 		if (mlx5_esw_vport_match_metadata_supported(dev->priv.eswitch)) {
608 			dev->priv.eswitch->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
609 			value.vbool = true;
610 		} else {
611 			value.vbool = false;
612 		}
613 		devlink_param_driverinit_value_set(devlink,
614 						   MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
615 						   value);
616 	}
617 #endif
618 
619 	value.vu32 = MLX5_COMP_EQ_SIZE;
620 	devlink_param_driverinit_value_set(devlink,
621 					   DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
622 					   value);
623 
624 	value.vu32 = MLX5_NUM_ASYNC_EQE;
625 	devlink_param_driverinit_value_set(devlink,
626 					   DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
627 					   value);
628 }
629 
630 static const struct devlink_param enable_eth_param =
631 	DEVLINK_PARAM_GENERIC(ENABLE_ETH, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
632 			      NULL, NULL, NULL);
633 
634 static int mlx5_devlink_eth_param_register(struct devlink *devlink)
635 {
636 	struct mlx5_core_dev *dev = devlink_priv(devlink);
637 	union devlink_param_value value;
638 	int err;
639 
640 	if (!mlx5_eth_supported(dev))
641 		return 0;
642 
643 	err = devlink_param_register(devlink, &enable_eth_param);
644 	if (err)
645 		return err;
646 
647 	value.vbool = true;
648 	devlink_param_driverinit_value_set(devlink,
649 					   DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
650 					   value);
651 	return 0;
652 }
653 
654 static void mlx5_devlink_eth_param_unregister(struct devlink *devlink)
655 {
656 	struct mlx5_core_dev *dev = devlink_priv(devlink);
657 
658 	if (!mlx5_eth_supported(dev))
659 		return;
660 
661 	devlink_param_unregister(devlink, &enable_eth_param);
662 }
663 
664 static int mlx5_devlink_enable_rdma_validate(struct devlink *devlink, u32 id,
665 					     union devlink_param_value val,
666 					     struct netlink_ext_ack *extack)
667 {
668 	struct mlx5_core_dev *dev = devlink_priv(devlink);
669 	bool new_state = val.vbool;
670 
671 	if (new_state && !mlx5_rdma_supported(dev))
672 		return -EOPNOTSUPP;
673 	return 0;
674 }
675 
676 static const struct devlink_param enable_rdma_param =
677 	DEVLINK_PARAM_GENERIC(ENABLE_RDMA, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
678 			      NULL, NULL, mlx5_devlink_enable_rdma_validate);
679 
680 static int mlx5_devlink_rdma_param_register(struct devlink *devlink)
681 {
682 	union devlink_param_value value;
683 	int err;
684 
685 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
686 		return 0;
687 
688 	err = devlink_param_register(devlink, &enable_rdma_param);
689 	if (err)
690 		return err;
691 
692 	value.vbool = true;
693 	devlink_param_driverinit_value_set(devlink,
694 					   DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
695 					   value);
696 	return 0;
697 }
698 
699 static void mlx5_devlink_rdma_param_unregister(struct devlink *devlink)
700 {
701 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
702 		return;
703 
704 	devlink_param_unregister(devlink, &enable_rdma_param);
705 }
706 
707 static const struct devlink_param enable_vnet_param =
708 	DEVLINK_PARAM_GENERIC(ENABLE_VNET, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
709 			      NULL, NULL, NULL);
710 
711 static int mlx5_devlink_vnet_param_register(struct devlink *devlink)
712 {
713 	struct mlx5_core_dev *dev = devlink_priv(devlink);
714 	union devlink_param_value value;
715 	int err;
716 
717 	if (!mlx5_vnet_supported(dev))
718 		return 0;
719 
720 	err = devlink_param_register(devlink, &enable_vnet_param);
721 	if (err)
722 		return err;
723 
724 	value.vbool = true;
725 	devlink_param_driverinit_value_set(devlink,
726 					   DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
727 					   value);
728 	return 0;
729 }
730 
731 static void mlx5_devlink_vnet_param_unregister(struct devlink *devlink)
732 {
733 	struct mlx5_core_dev *dev = devlink_priv(devlink);
734 
735 	if (!mlx5_vnet_supported(dev))
736 		return;
737 
738 	devlink_param_unregister(devlink, &enable_vnet_param);
739 }
740 
741 static int mlx5_devlink_auxdev_params_register(struct devlink *devlink)
742 {
743 	int err;
744 
745 	err = mlx5_devlink_eth_param_register(devlink);
746 	if (err)
747 		return err;
748 
749 	err = mlx5_devlink_rdma_param_register(devlink);
750 	if (err)
751 		goto rdma_err;
752 
753 	err = mlx5_devlink_vnet_param_register(devlink);
754 	if (err)
755 		goto vnet_err;
756 	return 0;
757 
758 vnet_err:
759 	mlx5_devlink_rdma_param_unregister(devlink);
760 rdma_err:
761 	mlx5_devlink_eth_param_unregister(devlink);
762 	return err;
763 }
764 
765 static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
766 {
767 	mlx5_devlink_vnet_param_unregister(devlink);
768 	mlx5_devlink_rdma_param_unregister(devlink);
769 	mlx5_devlink_eth_param_unregister(devlink);
770 }
771 
772 static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
773 					     union devlink_param_value val,
774 					     struct netlink_ext_ack *extack)
775 {
776 	struct mlx5_core_dev *dev = devlink_priv(devlink);
777 
778 	if (val.vu32 == 0) {
779 		NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
780 		return -EINVAL;
781 	}
782 
783 	if (!is_power_of_2(val.vu32)) {
784 		NL_SET_ERR_MSG_MOD(extack, "Only power of 2 values are supported for max_macs");
785 		return -EINVAL;
786 	}
787 
788 	if (ilog2(val.vu32) >
789 	    MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
790 		NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
791 		return -EINVAL;
792 	}
793 
794 	return 0;
795 }
796 
797 static const struct devlink_param max_uc_list_param =
798 	DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
799 			      NULL, NULL, mlx5_devlink_max_uc_list_validate);
800 
801 static int mlx5_devlink_max_uc_list_param_register(struct devlink *devlink)
802 {
803 	struct mlx5_core_dev *dev = devlink_priv(devlink);
804 	union devlink_param_value value;
805 	int err;
806 
807 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
808 		return 0;
809 
810 	err = devlink_param_register(devlink, &max_uc_list_param);
811 	if (err)
812 		return err;
813 
814 	value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
815 	devlink_param_driverinit_value_set(devlink,
816 					   DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
817 					   value);
818 	return 0;
819 }
820 
821 static void
822 mlx5_devlink_max_uc_list_param_unregister(struct devlink *devlink)
823 {
824 	struct mlx5_core_dev *dev = devlink_priv(devlink);
825 
826 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
827 		return;
828 
829 	devlink_param_unregister(devlink, &max_uc_list_param);
830 }
831 
832 #define MLX5_TRAP_DROP(_id, _group_id)					\
833 	DEVLINK_TRAP_GENERIC(DROP, DROP, _id,				\
834 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
835 			     DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
836 
837 static const struct devlink_trap mlx5_traps_arr[] = {
838 	MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
839 	MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
840 };
841 
842 static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
843 	DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
844 };
845 
846 static int mlx5_devlink_traps_register(struct devlink *devlink)
847 {
848 	struct mlx5_core_dev *core_dev = devlink_priv(devlink);
849 	int err;
850 
851 	err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr,
852 					   ARRAY_SIZE(mlx5_trap_groups_arr));
853 	if (err)
854 		return err;
855 
856 	err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
857 				     &core_dev->priv);
858 	if (err)
859 		goto err_trap_group;
860 	return 0;
861 
862 err_trap_group:
863 	devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
864 				       ARRAY_SIZE(mlx5_trap_groups_arr));
865 	return err;
866 }
867 
868 static void mlx5_devlink_traps_unregister(struct devlink *devlink)
869 {
870 	devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
871 	devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
872 				       ARRAY_SIZE(mlx5_trap_groups_arr));
873 }
874 
875 int mlx5_devlink_register(struct devlink *devlink)
876 {
877 	struct mlx5_core_dev *dev = devlink_priv(devlink);
878 	int err;
879 
880 	err = devlink_params_register(devlink, mlx5_devlink_params,
881 				      ARRAY_SIZE(mlx5_devlink_params));
882 	if (err)
883 		return err;
884 
885 	mlx5_devlink_set_params_init_values(devlink);
886 
887 	err = mlx5_devlink_auxdev_params_register(devlink);
888 	if (err)
889 		goto auxdev_reg_err;
890 
891 	err = mlx5_devlink_max_uc_list_param_register(devlink);
892 	if (err)
893 		goto max_uc_list_err;
894 
895 	err = mlx5_devlink_traps_register(devlink);
896 	if (err)
897 		goto traps_reg_err;
898 
899 	if (!mlx5_core_is_mp_slave(dev))
900 		devlink_set_features(devlink, DEVLINK_F_RELOAD);
901 
902 	return 0;
903 
904 traps_reg_err:
905 	mlx5_devlink_max_uc_list_param_unregister(devlink);
906 max_uc_list_err:
907 	mlx5_devlink_auxdev_params_unregister(devlink);
908 auxdev_reg_err:
909 	devlink_params_unregister(devlink, mlx5_devlink_params,
910 				  ARRAY_SIZE(mlx5_devlink_params));
911 	return err;
912 }
913 
914 void mlx5_devlink_unregister(struct devlink *devlink)
915 {
916 	mlx5_devlink_traps_unregister(devlink);
917 	mlx5_devlink_max_uc_list_param_unregister(devlink);
918 	mlx5_devlink_auxdev_params_unregister(devlink);
919 	devlink_params_unregister(devlink, mlx5_devlink_params,
920 				  ARRAY_SIZE(mlx5_devlink_params));
921 }
922