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