xref: /linux/drivers/net/ethernet/mellanox/mlx5/core/devlink.c (revision f2161d5f1aae21a42b0a64d87e10cb31db423f42)
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 #include "lib/nv_param.h"
14 
mlx5_devlink_flash_update(struct devlink * devlink,struct devlink_flash_update_params * params,struct netlink_ext_ack * extack)15 static int mlx5_devlink_flash_update(struct devlink *devlink,
16 				     struct devlink_flash_update_params *params,
17 				     struct netlink_ext_ack *extack)
18 {
19 	struct mlx5_core_dev *dev = devlink_priv(devlink);
20 
21 	return mlx5_firmware_flash(dev, params->fw, extack);
22 }
23 
mlx5_fw_ver_major(u32 version)24 static u8 mlx5_fw_ver_major(u32 version)
25 {
26 	return (version >> 24) & 0xff;
27 }
28 
mlx5_fw_ver_minor(u32 version)29 static u8 mlx5_fw_ver_minor(u32 version)
30 {
31 	return (version >> 16) & 0xff;
32 }
33 
mlx5_fw_ver_subminor(u32 version)34 static u16 mlx5_fw_ver_subminor(u32 version)
35 {
36 	return version & 0xffff;
37 }
38 
mlx5_devlink_serial_numbers_put(struct mlx5_core_dev * dev,struct devlink_info_req * req,struct netlink_ext_ack * extack)39 static int mlx5_devlink_serial_numbers_put(struct mlx5_core_dev *dev,
40 					   struct devlink_info_req *req,
41 					   struct netlink_ext_ack *extack)
42 {
43 	struct pci_dev *pdev = dev->pdev;
44 	unsigned int vpd_size, kw_len;
45 	char *str, *end;
46 	u8 *vpd_data;
47 	int err = 0;
48 	int start;
49 
50 	vpd_data = pci_vpd_alloc(pdev, &vpd_size);
51 	if (IS_ERR(vpd_data))
52 		return 0;
53 
54 	start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
55 					     PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len);
56 	if (start >= 0) {
57 		str = kstrndup(vpd_data + start, kw_len, GFP_KERNEL);
58 		if (!str) {
59 			err = -ENOMEM;
60 			goto end;
61 		}
62 		end = strchrnul(str, ' ');
63 		*end = '\0';
64 		err = devlink_info_board_serial_number_put(req, str);
65 		kfree(str);
66 		if (err)
67 			goto end;
68 	}
69 
70 	start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, "V3", &kw_len);
71 	if (start >= 0) {
72 		str = kstrndup(vpd_data + start, kw_len, GFP_KERNEL);
73 		if (!str) {
74 			err = -ENOMEM;
75 			goto end;
76 		}
77 		err = devlink_info_serial_number_put(req, str);
78 		kfree(str);
79 		if (err)
80 			goto end;
81 	}
82 
83 end:
84 	kfree(vpd_data);
85 	return err;
86 }
87 
88 #define DEVLINK_FW_STRING_LEN 32
89 
90 static int
mlx5_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)91 mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
92 		      struct netlink_ext_ack *extack)
93 {
94 	struct mlx5_core_dev *dev = devlink_priv(devlink);
95 	char version_str[DEVLINK_FW_STRING_LEN];
96 	u32 running_fw, stored_fw;
97 	int err;
98 
99 	if (!mlx5_core_is_pf(dev))
100 		return 0;
101 
102 	err = mlx5_devlink_serial_numbers_put(dev, req, extack);
103 	if (err)
104 		return err;
105 
106 	err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
107 	if (err)
108 		return err;
109 
110 	err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
111 	if (err)
112 		return err;
113 
114 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
115 		 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
116 		 mlx5_fw_ver_subminor(running_fw));
117 	err = devlink_info_version_running_put(req, "fw.version", version_str);
118 	if (err)
119 		return err;
120 	err = devlink_info_version_running_put(req,
121 					       DEVLINK_INFO_VERSION_GENERIC_FW,
122 					       version_str);
123 	if (err)
124 		return err;
125 
126 	/* no pending version, return running (stored) version */
127 	if (stored_fw == 0)
128 		stored_fw = running_fw;
129 
130 	snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
131 		 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
132 		 mlx5_fw_ver_subminor(stored_fw));
133 	err = devlink_info_version_stored_put(req, "fw.version", version_str);
134 	if (err)
135 		return err;
136 	return devlink_info_version_stored_put(req,
137 					       DEVLINK_INFO_VERSION_GENERIC_FW,
138 					       version_str);
139 }
140 
mlx5_devlink_reload_fw_activate(struct devlink * devlink,struct netlink_ext_ack * extack)141 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
142 {
143 	struct mlx5_core_dev *dev = devlink_priv(devlink);
144 	u8 reset_level, reset_type, net_port_alive;
145 	int err;
146 
147 	err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
148 	if (err)
149 		return err;
150 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
151 		NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
152 		return -EINVAL;
153 	}
154 
155 	net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
156 	err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive, extack);
157 	if (err)
158 		return err;
159 
160 	err = mlx5_fw_reset_wait_reset_done(dev);
161 	if (err)
162 		return err;
163 
164 	mlx5_sync_reset_unload_flow(dev, true);
165 	err = mlx5_health_wait_pci_up(dev);
166 	if (err)
167 		NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
168 
169 	return err;
170 }
171 
mlx5_devlink_trigger_fw_live_patch(struct devlink * devlink,struct netlink_ext_ack * extack)172 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
173 					      struct netlink_ext_ack *extack)
174 {
175 	struct mlx5_core_dev *dev = devlink_priv(devlink);
176 	u8 reset_level;
177 	int err;
178 
179 	err = mlx5_fw_reset_query(dev, &reset_level, NULL);
180 	if (err)
181 		return err;
182 	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
183 		NL_SET_ERR_MSG_MOD(extack,
184 				   "FW upgrade to the stored FW can't be done by FW live patching");
185 		return -EINVAL;
186 	}
187 
188 	return mlx5_fw_reset_set_live_patch(dev);
189 }
190 
mlx5_devlink_reload_down(struct devlink * devlink,bool netns_change,enum devlink_reload_action action,enum devlink_reload_limit limit,struct netlink_ext_ack * extack)191 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
192 				    enum devlink_reload_action action,
193 				    enum devlink_reload_limit limit,
194 				    struct netlink_ext_ack *extack)
195 {
196 	struct mlx5_core_dev *dev = devlink_priv(devlink);
197 	struct pci_dev *pdev = dev->pdev;
198 	int ret = 0;
199 
200 	if (mlx5_fw_reset_in_progress(dev)) {
201 		NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset");
202 		return -EBUSY;
203 	}
204 
205 	if (mlx5_dev_is_lightweight(dev)) {
206 		if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
207 			return -EOPNOTSUPP;
208 		mlx5_unload_one_light(dev);
209 		return 0;
210 	}
211 
212 	if (mlx5_core_is_mp_slave(dev)) {
213 		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported for multi port slave");
214 		return -EOPNOTSUPP;
215 	}
216 
217 	if (action == DEVLINK_RELOAD_ACTION_FW_ACTIVATE &&
218 	    !dev->priv.fw_reset) {
219 		NL_SET_ERR_MSG_MOD(extack, "FW activate is unsupported for this function");
220 		return -EOPNOTSUPP;
221 	}
222 
223 	if (mlx5_core_is_pf(dev) && pci_num_vf(pdev))
224 		NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
225 
226 	switch (action) {
227 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
228 		mlx5_unload_one_devl_locked(dev, false);
229 		break;
230 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
231 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
232 			ret = mlx5_devlink_trigger_fw_live_patch(devlink, extack);
233 		else
234 			ret = mlx5_devlink_reload_fw_activate(devlink, extack);
235 		break;
236 	default:
237 		/* Unsupported action should not get to this function */
238 		WARN_ON(1);
239 		ret = -EOPNOTSUPP;
240 	}
241 
242 	return ret;
243 }
244 
mlx5_devlink_reload_up(struct devlink * devlink,enum devlink_reload_action action,enum devlink_reload_limit limit,u32 * actions_performed,struct netlink_ext_ack * extack)245 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
246 				  enum devlink_reload_limit limit, u32 *actions_performed,
247 				  struct netlink_ext_ack *extack)
248 {
249 	struct mlx5_core_dev *dev = devlink_priv(devlink);
250 	int ret = 0;
251 
252 	*actions_performed = BIT(action);
253 	switch (action) {
254 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
255 		if (mlx5_dev_is_lightweight(dev)) {
256 			mlx5_fw_reporters_create(dev);
257 			return mlx5_init_one_devl_locked(dev);
258 		}
259 		ret = mlx5_load_one_devl_locked(dev, false);
260 		break;
261 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
262 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
263 			break;
264 		/* On fw_activate action, also driver is reloaded and reinit performed */
265 		*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
266 		ret = mlx5_load_one_devl_locked(dev, true);
267 		if (ret)
268 			return ret;
269 		ret = mlx5_fw_reset_verify_fw_complete(dev, extack);
270 		break;
271 	default:
272 		/* Unsupported action should not get to this function */
273 		WARN_ON(1);
274 		ret = -EOPNOTSUPP;
275 	}
276 
277 	return ret;
278 }
279 
mlx5_find_trap_by_id(struct mlx5_core_dev * dev,int trap_id)280 static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
281 {
282 	struct mlx5_devlink_trap *dl_trap;
283 
284 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
285 		if (dl_trap->trap.id == trap_id)
286 			return dl_trap;
287 
288 	return NULL;
289 }
290 
mlx5_devlink_trap_init(struct devlink * devlink,const struct devlink_trap * trap,void * trap_ctx)291 static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
292 				  void *trap_ctx)
293 {
294 	struct mlx5_core_dev *dev = devlink_priv(devlink);
295 	struct mlx5_devlink_trap *dl_trap;
296 
297 	dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
298 	if (!dl_trap)
299 		return -ENOMEM;
300 
301 	dl_trap->trap.id = trap->id;
302 	dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
303 	dl_trap->item = trap_ctx;
304 
305 	if (mlx5_find_trap_by_id(dev, trap->id)) {
306 		kfree(dl_trap);
307 		mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
308 		return -EEXIST;
309 	}
310 
311 	list_add_tail(&dl_trap->list, &dev->priv.traps);
312 	return 0;
313 }
314 
mlx5_devlink_trap_fini(struct devlink * devlink,const struct devlink_trap * trap,void * trap_ctx)315 static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
316 				   void *trap_ctx)
317 {
318 	struct mlx5_core_dev *dev = devlink_priv(devlink);
319 	struct mlx5_devlink_trap *dl_trap;
320 
321 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
322 	if (!dl_trap) {
323 		mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
324 		return;
325 	}
326 	list_del(&dl_trap->list);
327 	kfree(dl_trap);
328 }
329 
mlx5_devlink_trap_action_set(struct devlink * devlink,const struct devlink_trap * trap,enum devlink_trap_action action,struct netlink_ext_ack * extack)330 static int mlx5_devlink_trap_action_set(struct devlink *devlink,
331 					const struct devlink_trap *trap,
332 					enum devlink_trap_action action,
333 					struct netlink_ext_ack *extack)
334 {
335 	struct mlx5_core_dev *dev = devlink_priv(devlink);
336 	struct mlx5_devlink_trap_event_ctx trap_event_ctx;
337 	enum devlink_trap_action action_orig;
338 	struct mlx5_devlink_trap *dl_trap;
339 	int err;
340 
341 	if (is_mdev_switchdev_mode(dev)) {
342 		NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
343 		return -EOPNOTSUPP;
344 	}
345 
346 	dl_trap = mlx5_find_trap_by_id(dev, trap->id);
347 	if (!dl_trap) {
348 		mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
349 		return -EINVAL;
350 	}
351 
352 	if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP)
353 		return -EOPNOTSUPP;
354 
355 	if (action == dl_trap->trap.action)
356 		return 0;
357 
358 	action_orig = dl_trap->trap.action;
359 	dl_trap->trap.action = action;
360 	trap_event_ctx.trap = &dl_trap->trap;
361 	trap_event_ctx.err = 0;
362 	err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
363 						&trap_event_ctx);
364 	if (err == NOTIFY_BAD)
365 		dl_trap->trap.action = action_orig;
366 
367 	return trap_event_ctx.err;
368 }
369 
370 static const struct devlink_ops mlx5_devlink_ops = {
371 #ifdef CONFIG_MLX5_ESWITCH
372 	.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
373 	.eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
374 	.eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
375 	.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
376 	.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
377 	.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
378 	.rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
379 	.rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
380 	.rate_leaf_tc_bw_set = mlx5_esw_devlink_rate_leaf_tc_bw_set,
381 	.rate_node_tc_bw_set = mlx5_esw_devlink_rate_node_tc_bw_set,
382 	.rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
383 	.rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
384 	.rate_node_new = mlx5_esw_devlink_rate_node_new,
385 	.rate_node_del = mlx5_esw_devlink_rate_node_del,
386 	.rate_leaf_parent_set = mlx5_esw_devlink_rate_leaf_parent_set,
387 	.rate_node_parent_set = mlx5_esw_devlink_rate_node_parent_set,
388 #endif
389 #ifdef CONFIG_MLX5_SF_MANAGER
390 	.port_new = mlx5_devlink_sf_port_new,
391 #endif
392 	.flash_update = mlx5_devlink_flash_update,
393 	.info_get = mlx5_devlink_info_get,
394 	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
395 			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
396 	.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
397 	.reload_down = mlx5_devlink_reload_down,
398 	.reload_up = mlx5_devlink_reload_up,
399 	.trap_init = mlx5_devlink_trap_init,
400 	.trap_fini = mlx5_devlink_trap_fini,
401 	.trap_action_set = mlx5_devlink_trap_action_set,
402 };
403 
mlx5_devlink_trap_report(struct mlx5_core_dev * dev,int trap_id,struct sk_buff * skb,struct devlink_port * dl_port)404 void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
405 			      struct devlink_port *dl_port)
406 {
407 	struct devlink *devlink = priv_to_devlink(dev);
408 	struct mlx5_devlink_trap *dl_trap;
409 
410 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
411 	if (!dl_trap) {
412 		mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
413 		return;
414 	}
415 
416 	if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
417 		mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
418 			      dl_trap->trap.action);
419 		return;
420 	}
421 	devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
422 }
423 
mlx5_devlink_trap_get_num_active(struct mlx5_core_dev * dev)424 int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
425 {
426 	struct mlx5_devlink_trap *dl_trap;
427 	int count = 0;
428 
429 	list_for_each_entry(dl_trap, &dev->priv.traps, list)
430 		if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
431 			count++;
432 
433 	return count;
434 }
435 
mlx5_devlink_traps_get_action(struct mlx5_core_dev * dev,int trap_id,enum devlink_trap_action * action)436 int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
437 				  enum devlink_trap_action *action)
438 {
439 	struct mlx5_devlink_trap *dl_trap;
440 
441 	dl_trap = mlx5_find_trap_by_id(dev, trap_id);
442 	if (!dl_trap) {
443 		mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
444 			      trap_id);
445 		return -EINVAL;
446 	}
447 
448 	*action = dl_trap->trap.action;
449 	return 0;
450 }
451 
mlx5_devlink_alloc(struct device * dev)452 struct devlink *mlx5_devlink_alloc(struct device *dev)
453 {
454 	return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
455 			     dev);
456 }
457 
mlx5_devlink_free(struct devlink * devlink)458 void mlx5_devlink_free(struct devlink *devlink)
459 {
460 	devlink_free(devlink);
461 }
462 
mlx5_devlink_enable_roce_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)463 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
464 					     union devlink_param_value val,
465 					     struct netlink_ext_ack *extack)
466 {
467 	struct mlx5_core_dev *dev = devlink_priv(devlink);
468 	bool new_state = val.vbool;
469 
470 	if (new_state && !MLX5_CAP_GEN(dev, roce) &&
471 	    !(MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))) {
472 		NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
473 		return -EOPNOTSUPP;
474 	}
475 	if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
476 		NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
477 		return -EOPNOTSUPP;
478 	}
479 
480 	return 0;
481 }
482 
483 #ifdef CONFIG_MLX5_ESWITCH
mlx5_devlink_large_group_num_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)484 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
485 						 union devlink_param_value val,
486 						 struct netlink_ext_ack *extack)
487 {
488 	int group_num = val.vu32;
489 
490 	if (group_num < 1 || group_num > 1024) {
491 		NL_SET_ERR_MSG_MOD(extack,
492 				   "Unsupported group number, supported range is 1-1024");
493 		return -EOPNOTSUPP;
494 	}
495 
496 	return 0;
497 }
498 #endif
499 
mlx5_devlink_eq_depth_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)500 static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
501 					  union devlink_param_value val,
502 					  struct netlink_ext_ack *extack)
503 {
504 	return (val.vu32 >= 64 && val.vu32 <= 4096) ? 0 : -EINVAL;
505 }
506 
507 static int
mlx5_devlink_hairpin_num_queues_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)508 mlx5_devlink_hairpin_num_queues_validate(struct devlink *devlink, u32 id,
509 					 union devlink_param_value val,
510 					 struct netlink_ext_ack *extack)
511 {
512 	return val.vu32 ? 0 : -EINVAL;
513 }
514 
515 static int
mlx5_devlink_hairpin_queue_size_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)516 mlx5_devlink_hairpin_queue_size_validate(struct devlink *devlink, u32 id,
517 					 union devlink_param_value val,
518 					 struct netlink_ext_ack *extack)
519 {
520 	struct mlx5_core_dev *dev = devlink_priv(devlink);
521 	u32 val32 = val.vu32;
522 
523 	if (!is_power_of_2(val32)) {
524 		NL_SET_ERR_MSG_MOD(extack, "Value is not power of two");
525 		return -EINVAL;
526 	}
527 
528 	if (val32 > BIT(MLX5_CAP_GEN(dev, log_max_hairpin_num_packets))) {
529 		NL_SET_ERR_MSG_FMT_MOD(
530 			extack, "Maximum hairpin queue size is %lu",
531 			BIT(MLX5_CAP_GEN(dev, log_max_hairpin_num_packets)));
532 		return -EINVAL;
533 	}
534 
535 	return 0;
536 }
537 
mlx5_devlink_num_doorbells_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)538 static int mlx5_devlink_num_doorbells_validate(struct devlink *devlink, u32 id,
539 					       union devlink_param_value val,
540 					       struct netlink_ext_ack *extack)
541 {
542 	struct mlx5_core_dev *mdev = devlink_priv(devlink);
543 	u32 val32 = val.vu32;
544 	u32 max_num_channels;
545 
546 	max_num_channels = mlx5e_get_max_num_channels(mdev);
547 	if (val32 > max_num_channels) {
548 		NL_SET_ERR_MSG_FMT_MOD(extack,
549 				       "Requested num_doorbells (%u) exceeds max number of channels (%u)",
550 				       val32, max_num_channels);
551 		return -EINVAL;
552 	}
553 
554 	return 0;
555 }
556 
mlx5_devlink_hairpin_params_init_values(struct devlink * devlink)557 static void mlx5_devlink_hairpin_params_init_values(struct devlink *devlink)
558 {
559 	struct mlx5_core_dev *dev = devlink_priv(devlink);
560 	union devlink_param_value value;
561 	u32 link_speed = 0;
562 	u64 link_speed64;
563 
564 	/* set hairpin pair per each 50Gbs share of the link */
565 	mlx5_port_max_linkspeed(dev, &link_speed);
566 	link_speed = max_t(u32, link_speed, 50000);
567 	link_speed64 = link_speed;
568 	do_div(link_speed64, 50000);
569 
570 	value.vu32 = link_speed64;
571 	devl_param_driverinit_value_set(
572 		devlink, MLX5_DEVLINK_PARAM_ID_HAIRPIN_NUM_QUEUES, value);
573 
574 	value.vu32 =
575 		BIT(min_t(u32, 16 - MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(dev),
576 			  MLX5_CAP_GEN(dev, log_max_hairpin_num_packets)));
577 	devl_param_driverinit_value_set(
578 		devlink, MLX5_DEVLINK_PARAM_ID_HAIRPIN_QUEUE_SIZE, value);
579 }
580 
581 static const struct devlink_param mlx5_devlink_params[] = {
582 	DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
583 			      NULL, NULL, mlx5_devlink_enable_roce_validate),
584 #ifdef CONFIG_MLX5_ESWITCH
585 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
586 			     "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
587 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
588 			     NULL, NULL,
589 			     mlx5_devlink_large_group_num_validate),
590 #endif
591 	DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
592 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
593 	DEVLINK_PARAM_GENERIC(EVENT_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
594 			      NULL, NULL, mlx5_devlink_eq_depth_validate),
595 };
596 
mlx5_devlink_set_params_init_values(struct devlink * devlink)597 static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
598 {
599 	struct mlx5_core_dev *dev = devlink_priv(devlink);
600 	union devlink_param_value value;
601 
602 	value.vbool = MLX5_CAP_GEN(dev, roce) && !mlx5_dev_is_lightweight(dev);
603 	devl_param_driverinit_value_set(devlink,
604 					DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
605 					value);
606 
607 #ifdef CONFIG_MLX5_ESWITCH
608 	value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
609 	devl_param_driverinit_value_set(devlink,
610 					MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
611 					value);
612 #endif
613 
614 	value.vu32 = MLX5_COMP_EQ_SIZE;
615 	devl_param_driverinit_value_set(devlink,
616 					DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
617 					value);
618 
619 	value.vu32 = MLX5_NUM_ASYNC_EQE;
620 	devl_param_driverinit_value_set(devlink,
621 					DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
622 					value);
623 }
624 
625 static const struct devlink_param mlx5_devlink_eth_params[] = {
626 	DEVLINK_PARAM_GENERIC(ENABLE_ETH, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
627 			      NULL, NULL, NULL),
628 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_HAIRPIN_NUM_QUEUES,
629 			     "hairpin_num_queues", DEVLINK_PARAM_TYPE_U32,
630 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
631 			     mlx5_devlink_hairpin_num_queues_validate),
632 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_HAIRPIN_QUEUE_SIZE,
633 			     "hairpin_queue_size", DEVLINK_PARAM_TYPE_U32,
634 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
635 			     mlx5_devlink_hairpin_queue_size_validate),
636 	DEVLINK_PARAM_GENERIC(NUM_DOORBELLS,
637 			      BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
638 			      mlx5_devlink_num_doorbells_validate),
639 };
640 
mlx5_devlink_eth_params_register(struct devlink * devlink)641 static int mlx5_devlink_eth_params_register(struct devlink *devlink)
642 {
643 	struct mlx5_core_dev *dev = devlink_priv(devlink);
644 	union devlink_param_value value;
645 	int err;
646 
647 	if (!mlx5_eth_supported(dev))
648 		return 0;
649 
650 	err = devl_params_register(devlink, mlx5_devlink_eth_params,
651 				   ARRAY_SIZE(mlx5_devlink_eth_params));
652 	if (err)
653 		return err;
654 
655 	value.vbool = !mlx5_dev_is_lightweight(dev);
656 	devl_param_driverinit_value_set(devlink,
657 					DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
658 					value);
659 
660 	mlx5_devlink_hairpin_params_init_values(devlink);
661 
662 	value.vu32 = MLX5_DEFAULT_NUM_DOORBELLS;
663 	devl_param_driverinit_value_set(devlink,
664 					DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS,
665 					value);
666 	return 0;
667 }
668 
mlx5_devlink_eth_params_unregister(struct devlink * devlink)669 static void mlx5_devlink_eth_params_unregister(struct devlink *devlink)
670 {
671 	struct mlx5_core_dev *dev = devlink_priv(devlink);
672 
673 	if (!mlx5_eth_supported(dev))
674 		return;
675 
676 	devl_params_unregister(devlink, mlx5_devlink_eth_params,
677 			       ARRAY_SIZE(mlx5_devlink_eth_params));
678 }
679 
680 #define MLX5_PCIE_CONG_THRESH_MAX	10000
681 #define MLX5_PCIE_CONG_THRESH_DEF_LOW	7500
682 #define MLX5_PCIE_CONG_THRESH_DEF_HIGH	9000
683 
684 static int
mlx5_devlink_pcie_cong_thresh_validate(struct devlink * devl,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)685 mlx5_devlink_pcie_cong_thresh_validate(struct devlink *devl, u32 id,
686 				       union devlink_param_value val,
687 				       struct netlink_ext_ack *extack)
688 {
689 	if (val.vu16 > MLX5_PCIE_CONG_THRESH_MAX) {
690 		NL_SET_ERR_MSG_FMT_MOD(extack, "Value %u > max supported (%u)",
691 				       val.vu16, MLX5_PCIE_CONG_THRESH_MAX);
692 
693 		return -EINVAL;
694 	}
695 
696 	switch (id) {
697 	case MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_LOW:
698 	case MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_HIGH:
699 	case MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_LOW:
700 	case MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_HIGH:
701 		break;
702 	default:
703 		return -EOPNOTSUPP;
704 	}
705 
706 	return 0;
707 }
708 
mlx5_devlink_pcie_cong_init_values(struct devlink * devlink)709 static void mlx5_devlink_pcie_cong_init_values(struct devlink *devlink)
710 {
711 	union devlink_param_value value;
712 	u32 id;
713 
714 	value.vu16 = MLX5_PCIE_CONG_THRESH_DEF_LOW;
715 	id = MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_LOW;
716 	devl_param_driverinit_value_set(devlink, id, value);
717 
718 	value.vu16 = MLX5_PCIE_CONG_THRESH_DEF_HIGH;
719 	id = MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_HIGH;
720 	devl_param_driverinit_value_set(devlink, id, value);
721 
722 	value.vu16 = MLX5_PCIE_CONG_THRESH_DEF_LOW;
723 	id = MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_LOW;
724 	devl_param_driverinit_value_set(devlink, id, value);
725 
726 	value.vu16 = MLX5_PCIE_CONG_THRESH_DEF_HIGH;
727 	id = MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_HIGH;
728 	devl_param_driverinit_value_set(devlink, id, value);
729 }
730 
731 static const struct devlink_param mlx5_devlink_pcie_cong_params[] = {
732 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_LOW,
733 			     "pcie_cong_inbound_low", DEVLINK_PARAM_TYPE_U16,
734 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
735 			     mlx5_devlink_pcie_cong_thresh_validate),
736 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_HIGH,
737 			     "pcie_cong_inbound_high", DEVLINK_PARAM_TYPE_U16,
738 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
739 			     mlx5_devlink_pcie_cong_thresh_validate),
740 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_LOW,
741 			     "pcie_cong_outbound_low", DEVLINK_PARAM_TYPE_U16,
742 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
743 			     mlx5_devlink_pcie_cong_thresh_validate),
744 	DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_HIGH,
745 			     "pcie_cong_outbound_high", DEVLINK_PARAM_TYPE_U16,
746 			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL,
747 			     mlx5_devlink_pcie_cong_thresh_validate),
748 };
749 
mlx5_devlink_pcie_cong_params_register(struct devlink * devlink)750 static int mlx5_devlink_pcie_cong_params_register(struct devlink *devlink)
751 {
752 	struct mlx5_core_dev *dev = devlink_priv(devlink);
753 	int err;
754 
755 	if (!mlx5_pcie_cong_event_supported(dev))
756 		return 0;
757 
758 	err = devl_params_register(devlink, mlx5_devlink_pcie_cong_params,
759 				   ARRAY_SIZE(mlx5_devlink_pcie_cong_params));
760 	if (err)
761 		return err;
762 
763 	mlx5_devlink_pcie_cong_init_values(devlink);
764 
765 	return 0;
766 }
767 
mlx5_devlink_pcie_cong_params_unregister(struct devlink * devlink)768 static void mlx5_devlink_pcie_cong_params_unregister(struct devlink *devlink)
769 {
770 	struct mlx5_core_dev *dev = devlink_priv(devlink);
771 
772 	if (!mlx5_pcie_cong_event_supported(dev))
773 		return;
774 
775 	devl_params_unregister(devlink, mlx5_devlink_pcie_cong_params,
776 			       ARRAY_SIZE(mlx5_devlink_pcie_cong_params));
777 }
778 
mlx5_devlink_enable_rdma_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)779 static int mlx5_devlink_enable_rdma_validate(struct devlink *devlink, u32 id,
780 					     union devlink_param_value val,
781 					     struct netlink_ext_ack *extack)
782 {
783 	struct mlx5_core_dev *dev = devlink_priv(devlink);
784 	bool new_state = val.vbool;
785 
786 	if (new_state && !mlx5_rdma_supported(dev))
787 		return -EOPNOTSUPP;
788 	return 0;
789 }
790 
791 static const struct devlink_param mlx5_devlink_rdma_params[] = {
792 	DEVLINK_PARAM_GENERIC(ENABLE_RDMA, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
793 			      NULL, NULL, mlx5_devlink_enable_rdma_validate),
794 };
795 
mlx5_devlink_rdma_params_register(struct devlink * devlink)796 static int mlx5_devlink_rdma_params_register(struct devlink *devlink)
797 {
798 	struct mlx5_core_dev *dev = devlink_priv(devlink);
799 	union devlink_param_value value;
800 	int err;
801 
802 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
803 		return 0;
804 
805 	err = devl_params_register(devlink, mlx5_devlink_rdma_params,
806 				   ARRAY_SIZE(mlx5_devlink_rdma_params));
807 	if (err)
808 		return err;
809 
810 	value.vbool = !mlx5_dev_is_lightweight(dev);
811 	devl_param_driverinit_value_set(devlink,
812 					DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
813 					value);
814 	return 0;
815 }
816 
mlx5_devlink_rdma_params_unregister(struct devlink * devlink)817 static void mlx5_devlink_rdma_params_unregister(struct devlink *devlink)
818 {
819 	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
820 		return;
821 
822 	devl_params_unregister(devlink, mlx5_devlink_rdma_params,
823 			       ARRAY_SIZE(mlx5_devlink_rdma_params));
824 }
825 
826 static const struct devlink_param mlx5_devlink_vnet_params[] = {
827 	DEVLINK_PARAM_GENERIC(ENABLE_VNET, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
828 			      NULL, NULL, NULL),
829 };
830 
mlx5_devlink_vnet_params_register(struct devlink * devlink)831 static int mlx5_devlink_vnet_params_register(struct devlink *devlink)
832 {
833 	struct mlx5_core_dev *dev = devlink_priv(devlink);
834 	union devlink_param_value value;
835 	int err;
836 
837 	if (!mlx5_vnet_supported(dev))
838 		return 0;
839 
840 	err = devl_params_register(devlink, mlx5_devlink_vnet_params,
841 				   ARRAY_SIZE(mlx5_devlink_vnet_params));
842 	if (err)
843 		return err;
844 
845 	value.vbool = !mlx5_dev_is_lightweight(dev);
846 	devl_param_driverinit_value_set(devlink,
847 					DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
848 					value);
849 	return 0;
850 }
851 
mlx5_devlink_vnet_params_unregister(struct devlink * devlink)852 static void mlx5_devlink_vnet_params_unregister(struct devlink *devlink)
853 {
854 	struct mlx5_core_dev *dev = devlink_priv(devlink);
855 
856 	if (!mlx5_vnet_supported(dev))
857 		return;
858 
859 	devl_params_unregister(devlink, mlx5_devlink_vnet_params,
860 			       ARRAY_SIZE(mlx5_devlink_vnet_params));
861 }
862 
mlx5_devlink_auxdev_params_register(struct devlink * devlink)863 static int mlx5_devlink_auxdev_params_register(struct devlink *devlink)
864 {
865 	int err;
866 
867 	err = mlx5_devlink_eth_params_register(devlink);
868 	if (err)
869 		return err;
870 
871 	err = mlx5_devlink_rdma_params_register(devlink);
872 	if (err)
873 		goto rdma_err;
874 
875 	err = mlx5_devlink_vnet_params_register(devlink);
876 	if (err)
877 		goto vnet_err;
878 	return 0;
879 
880 vnet_err:
881 	mlx5_devlink_rdma_params_unregister(devlink);
882 rdma_err:
883 	mlx5_devlink_eth_params_unregister(devlink);
884 	return err;
885 }
886 
mlx5_devlink_auxdev_params_unregister(struct devlink * devlink)887 static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
888 {
889 	mlx5_devlink_vnet_params_unregister(devlink);
890 	mlx5_devlink_rdma_params_unregister(devlink);
891 	mlx5_devlink_eth_params_unregister(devlink);
892 }
893 
mlx5_devlink_max_uc_list_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)894 static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
895 					     union devlink_param_value val,
896 					     struct netlink_ext_ack *extack)
897 {
898 	struct mlx5_core_dev *dev = devlink_priv(devlink);
899 
900 	if (val.vu32 == 0) {
901 		NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
902 		return -EINVAL;
903 	}
904 
905 	if (!is_power_of_2(val.vu32)) {
906 		NL_SET_ERR_MSG_MOD(extack, "Only power of 2 values are supported for max_macs");
907 		return -EINVAL;
908 	}
909 
910 	if (ilog2(val.vu32) >
911 	    MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
912 		NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
913 		return -EINVAL;
914 	}
915 
916 	return 0;
917 }
918 
919 static const struct devlink_param mlx5_devlink_max_uc_list_params[] = {
920 	DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
921 			      NULL, NULL, mlx5_devlink_max_uc_list_validate),
922 };
923 
mlx5_devlink_max_uc_list_params_register(struct devlink * devlink)924 static int mlx5_devlink_max_uc_list_params_register(struct devlink *devlink)
925 {
926 	struct mlx5_core_dev *dev = devlink_priv(devlink);
927 	union devlink_param_value value;
928 	int err;
929 
930 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
931 		return 0;
932 
933 	err = devl_params_register(devlink, mlx5_devlink_max_uc_list_params,
934 				   ARRAY_SIZE(mlx5_devlink_max_uc_list_params));
935 	if (err)
936 		return err;
937 
938 	value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
939 	devl_param_driverinit_value_set(devlink,
940 					DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
941 					value);
942 	return 0;
943 }
944 
945 static void
mlx5_devlink_max_uc_list_params_unregister(struct devlink * devlink)946 mlx5_devlink_max_uc_list_params_unregister(struct devlink *devlink)
947 {
948 	struct mlx5_core_dev *dev = devlink_priv(devlink);
949 
950 	if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
951 		return;
952 
953 	devl_params_unregister(devlink, mlx5_devlink_max_uc_list_params,
954 			       ARRAY_SIZE(mlx5_devlink_max_uc_list_params));
955 }
956 
957 #define MLX5_TRAP_DROP(_id, _group_id)					\
958 	DEVLINK_TRAP_GENERIC(DROP, DROP, _id,				\
959 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
960 			     DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
961 
962 static const struct devlink_trap mlx5_traps_arr[] = {
963 	MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
964 	MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
965 };
966 
967 static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
968 	DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
969 };
970 
mlx5_devlink_traps_register(struct devlink * devlink)971 int mlx5_devlink_traps_register(struct devlink *devlink)
972 {
973 	struct mlx5_core_dev *core_dev = devlink_priv(devlink);
974 	int err;
975 
976 	err = devl_trap_groups_register(devlink, mlx5_trap_groups_arr,
977 					ARRAY_SIZE(mlx5_trap_groups_arr));
978 	if (err)
979 		return err;
980 
981 	err = devl_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
982 				  &core_dev->priv);
983 	if (err)
984 		goto err_trap_group;
985 	return 0;
986 
987 err_trap_group:
988 	devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
989 				    ARRAY_SIZE(mlx5_trap_groups_arr));
990 	return err;
991 }
992 
mlx5_devlink_traps_unregister(struct devlink * devlink)993 void mlx5_devlink_traps_unregister(struct devlink *devlink)
994 {
995 	devl_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
996 	devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
997 				    ARRAY_SIZE(mlx5_trap_groups_arr));
998 }
999 
mlx5_devlink_params_register(struct devlink * devlink)1000 int mlx5_devlink_params_register(struct devlink *devlink)
1001 {
1002 	int err;
1003 
1004 	/* Here only the driver init params should be registered.
1005 	 * Runtime params should be registered by the code which
1006 	 * behaviour they configure.
1007 	 */
1008 
1009 	err = devl_params_register(devlink, mlx5_devlink_params,
1010 				   ARRAY_SIZE(mlx5_devlink_params));
1011 	if (err)
1012 		return err;
1013 
1014 	mlx5_devlink_set_params_init_values(devlink);
1015 
1016 	err = mlx5_devlink_auxdev_params_register(devlink);
1017 	if (err)
1018 		goto auxdev_reg_err;
1019 
1020 	err = mlx5_devlink_max_uc_list_params_register(devlink);
1021 	if (err)
1022 		goto max_uc_list_err;
1023 
1024 	err = mlx5_devlink_pcie_cong_params_register(devlink);
1025 	if (err)
1026 		goto pcie_cong_err;
1027 
1028 	err = mlx5_nv_param_register_dl_params(devlink);
1029 	if (err)
1030 		goto nv_param_err;
1031 
1032 	return 0;
1033 
1034 nv_param_err:
1035 	mlx5_devlink_pcie_cong_params_unregister(devlink);
1036 pcie_cong_err:
1037 	mlx5_devlink_max_uc_list_params_unregister(devlink);
1038 max_uc_list_err:
1039 	mlx5_devlink_auxdev_params_unregister(devlink);
1040 auxdev_reg_err:
1041 	devl_params_unregister(devlink, mlx5_devlink_params,
1042 			       ARRAY_SIZE(mlx5_devlink_params));
1043 	return err;
1044 }
1045 
mlx5_devlink_params_unregister(struct devlink * devlink)1046 void mlx5_devlink_params_unregister(struct devlink *devlink)
1047 {
1048 	mlx5_nv_param_unregister_dl_params(devlink);
1049 	mlx5_devlink_pcie_cong_params_unregister(devlink);
1050 	mlx5_devlink_max_uc_list_params_unregister(devlink);
1051 	mlx5_devlink_auxdev_params_unregister(devlink);
1052 	devl_params_unregister(devlink, mlx5_devlink_params,
1053 			       ARRAY_SIZE(mlx5_devlink_params));
1054 }
1055