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