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