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