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