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_version_fixed_put(req, "fw.psid", dev->board_id);
50 	if (err)
51 		return err;
52 
53 	err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
54 	if (err)
55 		return err;
56 
57 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
58 		 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
59 		 mlx5_fw_ver_subminor(running_fw));
60 	err = devlink_info_version_running_put(req, "fw.version", version_str);
61 	if (err)
62 		return err;
63 	err = devlink_info_version_running_put(req,
64 					       DEVLINK_INFO_VERSION_GENERIC_FW,
65 					       version_str);
66 	if (err)
67 		return err;
68 
69 	/* no pending version, return running (stored) version */
70 	if (stored_fw == 0)
71 		stored_fw = running_fw;
72 
73 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
74 		 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
75 		 mlx5_fw_ver_subminor(stored_fw));
76 	err = devlink_info_version_stored_put(req, "fw.version", version_str);
77 	if (err)
78 		return err;
79 	return devlink_info_version_stored_put(req,
80 					       DEVLINK_INFO_VERSION_GENERIC_FW,
81 					       version_str);
82 }
83 
84 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
85 {
86 	struct mlx5_core_dev *dev = devlink_priv(devlink);
87 	u8 reset_level, reset_type, net_port_alive;
88 	int err;
89 
90 	err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
91 	if (err)
92 		return err;
93 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
94 		NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
95 		return -EINVAL;
96 	}
97 
98 	net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
99 	err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive, extack);
100 	if (err)
101 		return err;
102 
103 	err = mlx5_fw_reset_wait_reset_done(dev);
104 	if (err)
105 		return err;
106 
107 	mlx5_unload_one_devl_locked(dev);
108 	err = mlx5_health_wait_pci_up(dev);
109 	if (err)
110 		NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
111 
112 	return err;
113 }
114 
115 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
116 					      struct netlink_ext_ack *extack)
117 {
118 	struct mlx5_core_dev *dev = devlink_priv(devlink);
119 	u8 reset_level;
120 	int err;
121 
122 	err = mlx5_fw_reset_query(dev, &reset_level, NULL);
123 	if (err)
124 		return err;
125 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
126 		NL_SET_ERR_MSG_MOD(extack,
127 				   "FW upgrade to the stored FW can't be done by FW live patching");
128 		return -EINVAL;
129 	}
130 
131 	return mlx5_fw_reset_set_live_patch(dev);
132 }
133 
134 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
135 				    enum devlink_reload_action action,
136 				    enum devlink_reload_limit limit,
137 				    struct netlink_ext_ack *extack)
138 {
139 	struct mlx5_core_dev *dev = devlink_priv(devlink);
140 	struct pci_dev *pdev = dev->pdev;
141 	bool sf_dev_allocated;
142 	int ret = 0;
143 
144 	sf_dev_allocated = mlx5_sf_dev_allocated(dev);
145 	if (sf_dev_allocated) {
146 		/* Reload results in deleting SF device which further results in
147 		 * unregistering devlink instance while holding devlink_mutext.
148 		 * Hence, do not support reload.
149 		 */
150 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
151 		return -EOPNOTSUPP;
152 	}
153 
154 	if (mlx5_lag_is_active(dev)) {
155 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
156 		return -EOPNOTSUPP;
157 	}
158 
159 	if (pci_num_vf(pdev)) {
160 		NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
161 	}
162 
163 	switch (action) {
164 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
165 		mlx5_unload_one_devl_locked(dev);
166 		break;
167 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
168 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
169 			ret = mlx5_devlink_trigger_fw_live_patch(devlink, extack);
170 		else
171 			ret = mlx5_devlink_reload_fw_activate(devlink, extack);
172 		break;
173 	default:
174 		/* Unsupported action should not get to this function */
175 		WARN_ON(1);
176 		ret = -EOPNOTSUPP;
177 	}
178 
179 	return ret;
180 }
181 
182 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
183 				  enum devlink_reload_limit limit, u32 *actions_performed,
184 				  struct netlink_ext_ack *extack)
185 {
186 	struct mlx5_core_dev *dev = devlink_priv(devlink);
187 	int ret = 0;
188 
189 	*actions_performed = BIT(action);
190 	switch (action) {
191 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
192 		ret = mlx5_load_one_devl_locked(dev, false);
193 		break;
194 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
195 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
196 			break;
197 		/* On fw_activate action, also driver is reloaded and reinit performed */
198 		*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
199 		ret = mlx5_load_one_devl_locked(dev, false);
200 		break;
201 	default:
202 		/* Unsupported action should not get to this function */
203 		WARN_ON(1);
204 		ret = -EOPNOTSUPP;
205 	}
206 
207 	return ret;
208 }
209 
210 static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
211 {
212 	struct mlx5_devlink_trap *dl_trap;
213 
214 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
215 		if (dl_trap->trap.id == trap_id)
216 			return dl_trap;
217 
218 	return NULL;
219 }
220 
221 static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
222 				  void *trap_ctx)
223 {
224 	struct mlx5_core_dev *dev = devlink_priv(devlink);
225 	struct mlx5_devlink_trap *dl_trap;
226 
227 	dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
228 	if (!dl_trap)
229 		return -ENOMEM;
230 
231 	dl_trap->trap.id = trap->id;
232 	dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
233 	dl_trap->item = trap_ctx;
234 
235 	if (mlx5_find_trap_by_id(dev, trap->id)) {
236 		kfree(dl_trap);
237 		mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
238 		return -EEXIST;
239 	}
240 
241 	list_add_tail(&dl_trap->list, &dev->priv.traps);
242 	return 0;
243 }
244 
245 static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
246 				   void *trap_ctx)
247 {
248 	struct mlx5_core_dev *dev = devlink_priv(devlink);
249 	struct mlx5_devlink_trap *dl_trap;
250 
251 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
252 	if (!dl_trap) {
253 		mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
254 		return;
255 	}
256 	list_del(&dl_trap->list);
257 	kfree(dl_trap);
258 }
259 
260 static int mlx5_devlink_trap_action_set(struct devlink *devlink,
261 					const struct devlink_trap *trap,
262 					enum devlink_trap_action action,
263 					struct netlink_ext_ack *extack)
264 {
265 	struct mlx5_core_dev *dev = devlink_priv(devlink);
266 	enum devlink_trap_action action_orig;
267 	struct mlx5_devlink_trap *dl_trap;
268 	int err = 0;
269 
270 	if (is_mdev_switchdev_mode(dev)) {
271 		NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
272 		return -EOPNOTSUPP;
273 	}
274 
275 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
276 	if (!dl_trap) {
277 		mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
278 		err = -EINVAL;
279 		goto out;
280 	}
281 
282 	if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
283 		err = -EOPNOTSUPP;
284 		goto out;
285 	}
286 
287 	if (action == dl_trap->trap.action)
288 		goto out;
289 
290 	action_orig = dl_trap->trap.action;
291 	dl_trap->trap.action = action;
292 	err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
293 						&dl_trap->trap);
294 	if (err)
295 		dl_trap->trap.action = action_orig;
296 out:
297 	return err;
298 }
299 
300 static const struct devlink_ops mlx5_devlink_ops = {
301 #ifdef CONFIG_MLX5_ESWITCH
302 	.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
303 	.eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
304 	.eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
305 	.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
306 	.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
307 	.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
308 	.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
309 	.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
310 	.rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
311 	.rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
312 	.rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
313 	.rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
314 	.rate_node_new = mlx5_esw_devlink_rate_node_new,
315 	.rate_node_del = mlx5_esw_devlink_rate_node_del,
316 	.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
317 	.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
318 	.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
319 	.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
320 	.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
321 #endif
322 #ifdef CONFIG_MLX5_SF_MANAGER
323 	.port_new = mlx5_devlink_sf_port_new,
324 	.port_del = mlx5_devlink_sf_port_del,
325 	.port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
326 	.port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
327 #endif
328 	.flash_update = mlx5_devlink_flash_update,
329 	.info_get = mlx5_devlink_info_get,
330 	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
331 			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
332 	.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
333 	.reload_down = mlx5_devlink_reload_down,
334 	.reload_up = mlx5_devlink_reload_up,
335 	.trap_init = mlx5_devlink_trap_init,
336 	.trap_fini = mlx5_devlink_trap_fini,
337 	.trap_action_set = mlx5_devlink_trap_action_set,
338 };
339 
340 void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
341 			      struct devlink_port *dl_port)
342 {
343 	struct devlink *devlink = priv_to_devlink(dev);
344 	struct mlx5_devlink_trap *dl_trap;
345 
346 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
347 	if (!dl_trap) {
348 		mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
349 		return;
350 	}
351 
352 	if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
353 		mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
354 			      dl_trap->trap.action);
355 		return;
356 	}
357 	devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
358 }
359 
360 int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
361 {
362 	struct mlx5_devlink_trap *dl_trap;
363 	int count = 0;
364 
365 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
366 		if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
367 			count++;
368 
369 	return count;
370 }
371 
372 int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
373 				  enum devlink_trap_action *action)
374 {
375 	struct mlx5_devlink_trap *dl_trap;
376 
377 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
378 	if (!dl_trap) {
379 		mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
380 			      trap_id);
381 		return -EINVAL;
382 	}
383 
384 	*action = dl_trap->trap.action;
385 	return 0;
386 }
387 
388 struct devlink *mlx5_devlink_alloc(struct device *dev)
389 {
390 	return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
391 			     dev);
392 }
393 
394 void mlx5_devlink_free(struct devlink *devlink)
395 {
396 	devlink_free(devlink);
397 }
398 
399 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
400 					     union devlink_param_value val,
401 					     struct netlink_ext_ack *extack)
402 {
403 	struct mlx5_core_dev *dev = devlink_priv(devlink);
404 	bool new_state = val.vbool;
405 
406 	if (new_state && !MLX5_CAP_GEN(dev, roce) &&
407 	    !(MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))) {
408 		NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
409 		return -EOPNOTSUPP;
410 	}
411 	if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
412 		NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
413 		return -EOPNOTSUPP;
414 	}
415 
416 	return 0;
417 }
418 
419 #ifdef CONFIG_MLX5_ESWITCH
420 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
421 						 union devlink_param_value val,
422 						 struct netlink_ext_ack *extack)
423 {
424 	int group_num = val.vu32;
425 
426 	if (group_num < 1 || group_num > 1024) {
427 		NL_SET_ERR_MSG_MOD(extack,
428 				   "Unsupported group number, supported range is 1-1024");
429 		return -EOPNOTSUPP;
430 	}
431 
432 	return 0;
433 }
434 
435 #endif
436 
437 static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
438 					  union devlink_param_value val,
439 					  struct netlink_ext_ack *extack)
440 {
441 	return (val.vu32 >= 64 && val.vu32 <= 4096) ? 0 : -EINVAL;
442 }
443 
444 static const struct devlink_param mlx5_devlink_params[] = {
445 	DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
446 			      NULL, NULL, mlx5_devlink_enable_roce_validate),
447 #ifdef CONFIG_MLX5_ESWITCH
448 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
449 			     "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
450 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
451 			     NULL, NULL,
452 			     mlx5_devlink_large_group_num_validate),
453 #endif
454 	DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
455 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
456 	DEVLINK_PARAM_GENERIC(EVENT_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
457 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
458 };
459 
460 static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
461 {
462 	struct mlx5_core_dev *dev = devlink_priv(devlink);
463 	union devlink_param_value value;
464 
465 	value.vbool = MLX5_CAP_GEN(dev, roce);
466 	devl_param_driverinit_value_set(devlink,
467 					DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
468 					value);
469 
470 #ifdef CONFIG_MLX5_ESWITCH
471 	value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
472 	devl_param_driverinit_value_set(devlink,
473 					MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
474 					value);
475 #endif
476 
477 	value.vu32 = MLX5_COMP_EQ_SIZE;
478 	devl_param_driverinit_value_set(devlink,
479 					DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
480 					value);
481 
482 	value.vu32 = MLX5_NUM_ASYNC_EQE;
483 	devl_param_driverinit_value_set(devlink,
484 					DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
485 					value);
486 }
487 
488 static const struct devlink_param mlx5_devlink_eth_params[] = {
489 	DEVLINK_PARAM_GENERIC(ENABLE_ETH, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
490 			      NULL, NULL, NULL),
491 };
492 
493 static int mlx5_devlink_eth_params_register(struct devlink *devlink)
494 {
495 	struct mlx5_core_dev *dev = devlink_priv(devlink);
496 	union devlink_param_value value;
497 	int err;
498 
499 	if (!mlx5_eth_supported(dev))
500 		return 0;
501 
502 	err = devl_params_register(devlink, mlx5_devlink_eth_params,
503 				   ARRAY_SIZE(mlx5_devlink_eth_params));
504 	if (err)
505 		return err;
506 
507 	value.vbool = true;
508 	devl_param_driverinit_value_set(devlink,
509 					DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
510 					value);
511 	return 0;
512 }
513 
514 static void mlx5_devlink_eth_params_unregister(struct devlink *devlink)
515 {
516 	struct mlx5_core_dev *dev = devlink_priv(devlink);
517 
518 	if (!mlx5_eth_supported(dev))
519 		return;
520 
521 	devl_params_unregister(devlink, mlx5_devlink_eth_params,
522 			       ARRAY_SIZE(mlx5_devlink_eth_params));
523 }
524 
525 static int mlx5_devlink_enable_rdma_validate(struct devlink *devlink, u32 id,
526 					     union devlink_param_value val,
527 					     struct netlink_ext_ack *extack)
528 {
529 	struct mlx5_core_dev *dev = devlink_priv(devlink);
530 	bool new_state = val.vbool;
531 
532 	if (new_state && !mlx5_rdma_supported(dev))
533 		return -EOPNOTSUPP;
534 	return 0;
535 }
536 
537 static const struct devlink_param mlx5_devlink_rdma_params[] = {
538 	DEVLINK_PARAM_GENERIC(ENABLE_RDMA, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
539 			      NULL, NULL, mlx5_devlink_enable_rdma_validate),
540 };
541 
542 static int mlx5_devlink_rdma_params_register(struct devlink *devlink)
543 {
544 	union devlink_param_value value;
545 	int err;
546 
547 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
548 		return 0;
549 
550 	err = devl_params_register(devlink, mlx5_devlink_rdma_params,
551 				   ARRAY_SIZE(mlx5_devlink_rdma_params));
552 	if (err)
553 		return err;
554 
555 	value.vbool = true;
556 	devl_param_driverinit_value_set(devlink,
557 					DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
558 					value);
559 	return 0;
560 }
561 
562 static void mlx5_devlink_rdma_params_unregister(struct devlink *devlink)
563 {
564 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
565 		return;
566 
567 	devl_params_unregister(devlink, mlx5_devlink_rdma_params,
568 			       ARRAY_SIZE(mlx5_devlink_rdma_params));
569 }
570 
571 static const struct devlink_param mlx5_devlink_vnet_params[] = {
572 	DEVLINK_PARAM_GENERIC(ENABLE_VNET, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
573 			      NULL, NULL, NULL),
574 };
575 
576 static int mlx5_devlink_vnet_params_register(struct devlink *devlink)
577 {
578 	struct mlx5_core_dev *dev = devlink_priv(devlink);
579 	union devlink_param_value value;
580 	int err;
581 
582 	if (!mlx5_vnet_supported(dev))
583 		return 0;
584 
585 	err = devl_params_register(devlink, mlx5_devlink_vnet_params,
586 				   ARRAY_SIZE(mlx5_devlink_vnet_params));
587 	if (err)
588 		return err;
589 
590 	value.vbool = true;
591 	devl_param_driverinit_value_set(devlink,
592 					DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
593 					value);
594 	return 0;
595 }
596 
597 static void mlx5_devlink_vnet_params_unregister(struct devlink *devlink)
598 {
599 	struct mlx5_core_dev *dev = devlink_priv(devlink);
600 
601 	if (!mlx5_vnet_supported(dev))
602 		return;
603 
604 	devl_params_unregister(devlink, mlx5_devlink_vnet_params,
605 			       ARRAY_SIZE(mlx5_devlink_vnet_params));
606 }
607 
608 static int mlx5_devlink_auxdev_params_register(struct devlink *devlink)
609 {
610 	int err;
611 
612 	err = mlx5_devlink_eth_params_register(devlink);
613 	if (err)
614 		return err;
615 
616 	err = mlx5_devlink_rdma_params_register(devlink);
617 	if (err)
618 		goto rdma_err;
619 
620 	err = mlx5_devlink_vnet_params_register(devlink);
621 	if (err)
622 		goto vnet_err;
623 	return 0;
624 
625 vnet_err:
626 	mlx5_devlink_rdma_params_unregister(devlink);
627 rdma_err:
628 	mlx5_devlink_eth_params_unregister(devlink);
629 	return err;
630 }
631 
632 static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
633 {
634 	mlx5_devlink_vnet_params_unregister(devlink);
635 	mlx5_devlink_rdma_params_unregister(devlink);
636 	mlx5_devlink_eth_params_unregister(devlink);
637 }
638 
639 static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
640 					     union devlink_param_value val,
641 					     struct netlink_ext_ack *extack)
642 {
643 	struct mlx5_core_dev *dev = devlink_priv(devlink);
644 
645 	if (val.vu32 == 0) {
646 		NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
647 		return -EINVAL;
648 	}
649 
650 	if (!is_power_of_2(val.vu32)) {
651 		NL_SET_ERR_MSG_MOD(extack, "Only power of 2 values are supported for max_macs");
652 		return -EINVAL;
653 	}
654 
655 	if (ilog2(val.vu32) >
656 	    MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
657 		NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
658 		return -EINVAL;
659 	}
660 
661 	return 0;
662 }
663 
664 static const struct devlink_param mlx5_devlink_max_uc_list_params[] = {
665 	DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
666 			      NULL, NULL, mlx5_devlink_max_uc_list_validate),
667 };
668 
669 static int mlx5_devlink_max_uc_list_params_register(struct devlink *devlink)
670 {
671 	struct mlx5_core_dev *dev = devlink_priv(devlink);
672 	union devlink_param_value value;
673 	int err;
674 
675 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
676 		return 0;
677 
678 	err = devl_params_register(devlink, mlx5_devlink_max_uc_list_params,
679 				   ARRAY_SIZE(mlx5_devlink_max_uc_list_params));
680 	if (err)
681 		return err;
682 
683 	value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
684 	devl_param_driverinit_value_set(devlink,
685 					DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
686 					value);
687 	return 0;
688 }
689 
690 static void
691 mlx5_devlink_max_uc_list_params_unregister(struct devlink *devlink)
692 {
693 	struct mlx5_core_dev *dev = devlink_priv(devlink);
694 
695 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
696 		return;
697 
698 	devl_params_unregister(devlink, mlx5_devlink_max_uc_list_params,
699 			       ARRAY_SIZE(mlx5_devlink_max_uc_list_params));
700 }
701 
702 #define MLX5_TRAP_DROP(_id, _group_id)					\
703 	DEVLINK_TRAP_GENERIC(DROP, DROP, _id,				\
704 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
705 			     DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
706 
707 static const struct devlink_trap mlx5_traps_arr[] = {
708 	MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
709 	MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
710 };
711 
712 static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
713 	DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
714 };
715 
716 int mlx5_devlink_traps_register(struct devlink *devlink)
717 {
718 	struct mlx5_core_dev *core_dev = devlink_priv(devlink);
719 	int err;
720 
721 	err = devl_trap_groups_register(devlink, mlx5_trap_groups_arr,
722 					ARRAY_SIZE(mlx5_trap_groups_arr));
723 	if (err)
724 		return err;
725 
726 	err = devl_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
727 				  &core_dev->priv);
728 	if (err)
729 		goto err_trap_group;
730 	return 0;
731 
732 err_trap_group:
733 	devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
734 				    ARRAY_SIZE(mlx5_trap_groups_arr));
735 	return err;
736 }
737 
738 void mlx5_devlink_traps_unregister(struct devlink *devlink)
739 {
740 	devl_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
741 	devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
742 				    ARRAY_SIZE(mlx5_trap_groups_arr));
743 }
744 
745 int mlx5_devlink_params_register(struct devlink *devlink)
746 {
747 	struct mlx5_core_dev *dev = devlink_priv(devlink);
748 	int err;
749 
750 	err = devl_params_register(devlink, mlx5_devlink_params,
751 				   ARRAY_SIZE(mlx5_devlink_params));
752 	if (err)
753 		return err;
754 
755 	mlx5_devlink_set_params_init_values(devlink);
756 
757 	err = mlx5_devlink_auxdev_params_register(devlink);
758 	if (err)
759 		goto auxdev_reg_err;
760 
761 	err = mlx5_devlink_max_uc_list_params_register(devlink);
762 	if (err)
763 		goto max_uc_list_err;
764 
765 	if (!mlx5_core_is_mp_slave(dev))
766 		devlink_set_features(devlink, DEVLINK_F_RELOAD);
767 
768 	return 0;
769 
770 max_uc_list_err:
771 	mlx5_devlink_auxdev_params_unregister(devlink);
772 auxdev_reg_err:
773 	devl_params_unregister(devlink, mlx5_devlink_params,
774 			       ARRAY_SIZE(mlx5_devlink_params));
775 	return err;
776 }
777 
778 void mlx5_devlink_params_unregister(struct devlink *devlink)
779 {
780 	mlx5_devlink_max_uc_list_params_unregister(devlink);
781 	mlx5_devlink_auxdev_params_unregister(devlink);
782 	devl_params_unregister(devlink, mlx5_devlink_params,
783 			       ARRAY_SIZE(mlx5_devlink_params));
784 }
785