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