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