1 /* 2 * Copyright (c) 2018 Cumulus Networks. All rights reserved. 3 * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com> 4 * Copyright (c) 2019 Mellanox Technologies. All rights reserved. 5 * 6 * This software is licensed under the GNU General License Version 2, 7 * June 1991 as shown in the file COPYING in the top-level directory of this 8 * source tree. 9 * 10 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" 11 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, 12 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE 14 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME 15 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16 */ 17 18 #include <linux/debugfs.h> 19 #include <linux/device.h> 20 #include <linux/etherdevice.h> 21 #include <linux/hex.h> 22 #include <linux/inet.h> 23 #include <linux/jiffies.h> 24 #include <linux/kernel.h> 25 #include <linux/list.h> 26 #include <linux/mutex.h> 27 #include <linux/random.h> 28 #include <linux/rtnetlink.h> 29 #include <linux/workqueue.h> 30 #include <net/devlink.h> 31 #include <net/ip.h> 32 #include <net/flow_offload.h> 33 #include <uapi/linux/devlink.h> 34 #include <uapi/linux/ip.h> 35 #include <uapi/linux/udp.h> 36 37 #include "netdevsim.h" 38 39 static unsigned int 40 nsim_dev_port_index(enum nsim_dev_port_type type, unsigned int port_index) 41 { 42 switch (type) { 43 case NSIM_DEV_PORT_TYPE_VF: 44 port_index = NSIM_DEV_VF_PORT_INDEX_BASE + port_index; 45 break; 46 case NSIM_DEV_PORT_TYPE_PF: 47 break; 48 } 49 50 return port_index; 51 } 52 53 static inline unsigned int nsim_dev_port_index_to_vf_index(unsigned int port_index) 54 { 55 return port_index - NSIM_DEV_VF_PORT_INDEX_BASE; 56 } 57 58 static struct dentry *nsim_dev_ddir; 59 60 unsigned int nsim_dev_get_vfs(struct nsim_dev *nsim_dev) 61 { 62 WARN_ON(!lockdep_rtnl_is_held() && 63 !devl_lock_is_held(priv_to_devlink(nsim_dev))); 64 65 return nsim_dev->nsim_bus_dev->num_vfs; 66 } 67 68 static void 69 nsim_bus_dev_set_vfs(struct nsim_bus_dev *nsim_bus_dev, unsigned int num_vfs) 70 { 71 rtnl_lock(); 72 nsim_bus_dev->num_vfs = num_vfs; 73 rtnl_unlock(); 74 } 75 76 #define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32) 77 78 static int 79 nsim_dev_take_snapshot(struct devlink *devlink, 80 const struct devlink_region_ops *ops, 81 struct netlink_ext_ack *extack, 82 u8 **data) 83 { 84 void *dummy_data; 85 86 dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL); 87 if (!dummy_data) 88 return -ENOMEM; 89 90 get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE); 91 92 *data = dummy_data; 93 94 return 0; 95 } 96 97 static ssize_t nsim_dev_take_snapshot_write(struct file *file, 98 const char __user *data, 99 size_t count, loff_t *ppos) 100 { 101 struct nsim_dev *nsim_dev = file->private_data; 102 struct devlink *devlink; 103 u8 *dummy_data; 104 int err; 105 u32 id; 106 107 devlink = priv_to_devlink(nsim_dev); 108 109 err = nsim_dev_take_snapshot(devlink, NULL, NULL, &dummy_data); 110 if (err) 111 return err; 112 113 err = devlink_region_snapshot_id_get(devlink, &id); 114 if (err) { 115 pr_err("Failed to get snapshot id\n"); 116 kfree(dummy_data); 117 return err; 118 } 119 err = devlink_region_snapshot_create(nsim_dev->dummy_region, 120 dummy_data, id); 121 devlink_region_snapshot_id_put(devlink, id); 122 if (err) { 123 pr_err("Failed to create region snapshot\n"); 124 kfree(dummy_data); 125 return err; 126 } 127 128 return count; 129 } 130 131 static const struct file_operations nsim_dev_take_snapshot_fops = { 132 .open = simple_open, 133 .write = nsim_dev_take_snapshot_write, 134 .llseek = generic_file_llseek, 135 .owner = THIS_MODULE, 136 }; 137 138 static ssize_t nsim_dev_trap_fa_cookie_read(struct file *file, 139 char __user *data, 140 size_t count, loff_t *ppos) 141 { 142 struct nsim_dev *nsim_dev = file->private_data; 143 struct flow_action_cookie *fa_cookie; 144 unsigned int buf_len; 145 ssize_t ret; 146 char *buf; 147 148 spin_lock(&nsim_dev->fa_cookie_lock); 149 fa_cookie = nsim_dev->fa_cookie; 150 if (!fa_cookie) { 151 ret = -EINVAL; 152 goto errout; 153 } 154 buf_len = fa_cookie->cookie_len * 2; 155 buf = kmalloc(buf_len, GFP_ATOMIC); 156 if (!buf) { 157 ret = -ENOMEM; 158 goto errout; 159 } 160 bin2hex(buf, fa_cookie->cookie, fa_cookie->cookie_len); 161 spin_unlock(&nsim_dev->fa_cookie_lock); 162 163 ret = simple_read_from_buffer(data, count, ppos, buf, buf_len); 164 165 kfree(buf); 166 return ret; 167 168 errout: 169 spin_unlock(&nsim_dev->fa_cookie_lock); 170 return ret; 171 } 172 173 static ssize_t nsim_dev_trap_fa_cookie_write(struct file *file, 174 const char __user *data, 175 size_t count, loff_t *ppos) 176 { 177 struct nsim_dev *nsim_dev = file->private_data; 178 struct flow_action_cookie *fa_cookie; 179 size_t cookie_len; 180 ssize_t ret; 181 char *buf; 182 183 if (*ppos != 0) 184 return -EINVAL; 185 cookie_len = (count - 1) / 2; 186 if ((count - 1) % 2) 187 return -EINVAL; 188 189 buf = memdup_user(data, count); 190 if (IS_ERR(buf)) 191 return PTR_ERR(buf); 192 193 fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len, 194 GFP_KERNEL | __GFP_NOWARN); 195 if (!fa_cookie) { 196 ret = -ENOMEM; 197 goto free_buf; 198 } 199 200 fa_cookie->cookie_len = cookie_len; 201 ret = hex2bin(fa_cookie->cookie, buf, cookie_len); 202 if (ret) 203 goto free_fa_cookie; 204 kfree(buf); 205 206 spin_lock(&nsim_dev->fa_cookie_lock); 207 kfree(nsim_dev->fa_cookie); 208 nsim_dev->fa_cookie = fa_cookie; 209 spin_unlock(&nsim_dev->fa_cookie_lock); 210 211 return count; 212 213 free_fa_cookie: 214 kfree(fa_cookie); 215 free_buf: 216 kfree(buf); 217 return ret; 218 } 219 220 static const struct file_operations nsim_dev_trap_fa_cookie_fops = { 221 .open = simple_open, 222 .read = nsim_dev_trap_fa_cookie_read, 223 .write = nsim_dev_trap_fa_cookie_write, 224 .llseek = generic_file_llseek, 225 .owner = THIS_MODULE, 226 }; 227 228 static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) 229 { 230 char dev_ddir_name[sizeof(DRV_NAME) + 10]; 231 int err; 232 233 sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id); 234 nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir); 235 if (IS_ERR(nsim_dev->ddir)) 236 return PTR_ERR(nsim_dev->ddir); 237 nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir); 238 if (IS_ERR(nsim_dev->ports_ddir)) { 239 err = PTR_ERR(nsim_dev->ports_ddir); 240 goto err_ddir; 241 } 242 debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir, 243 &nsim_dev->fw_update_status); 244 debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir, 245 &nsim_dev->fw_update_overwrite_mask); 246 debugfs_create_u32("fw_update_flash_chunk_time_ms", 0600, nsim_dev->ddir, 247 &nsim_dev->fw_update_flash_chunk_time_ms); 248 debugfs_create_u32("max_macs", 0600, nsim_dev->ddir, 249 &nsim_dev->max_macs); 250 debugfs_create_bool("test1", 0600, nsim_dev->ddir, 251 &nsim_dev->test1); 252 debugfs_create_u32("test2", 0600, nsim_dev->ddir, 253 &nsim_dev->test2); 254 nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 255 0200, 256 nsim_dev->ddir, 257 nsim_dev, 258 &nsim_dev_take_snapshot_fops); 259 debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir, 260 &nsim_dev->dont_allow_reload); 261 debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir, 262 &nsim_dev->fail_reload); 263 debugfs_create_file("trap_flow_action_cookie", 0600, nsim_dev->ddir, 264 nsim_dev, &nsim_dev_trap_fa_cookie_fops); 265 debugfs_create_bool("fail_trap_group_set", 0600, 266 nsim_dev->ddir, 267 &nsim_dev->fail_trap_group_set); 268 debugfs_create_bool("fail_trap_policer_set", 0600, 269 nsim_dev->ddir, 270 &nsim_dev->fail_trap_policer_set); 271 debugfs_create_bool("fail_trap_policer_counter_get", 0600, 272 nsim_dev->ddir, 273 &nsim_dev->fail_trap_policer_counter_get); 274 275 nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir); 276 if (IS_ERR(nsim_dev->nodes_ddir)) { 277 err = PTR_ERR(nsim_dev->nodes_ddir); 278 goto err_ports_ddir; 279 } 280 debugfs_create_bool("fail_trap_drop_counter_get", 0600, 281 nsim_dev->ddir, 282 &nsim_dev->fail_trap_drop_counter_get); 283 nsim_udp_tunnels_debugfs_create(nsim_dev); 284 return 0; 285 286 err_ports_ddir: 287 debugfs_remove_recursive(nsim_dev->ports_ddir); 288 err_ddir: 289 debugfs_remove_recursive(nsim_dev->ddir); 290 return err; 291 } 292 293 static void nsim_dev_debugfs_exit(struct nsim_dev *nsim_dev) 294 { 295 debugfs_remove_recursive(nsim_dev->nodes_ddir); 296 debugfs_remove_recursive(nsim_dev->ports_ddir); 297 debugfs_remove_recursive(nsim_dev->ddir); 298 } 299 300 static ssize_t nsim_dev_rate_parent_read(struct file *file, 301 char __user *data, 302 size_t count, loff_t *ppos) 303 { 304 char **name_ptr = file->private_data; 305 size_t len; 306 307 if (!*name_ptr) 308 return 0; 309 310 len = strlen(*name_ptr); 311 return simple_read_from_buffer(data, count, ppos, *name_ptr, len); 312 } 313 314 static const struct file_operations nsim_dev_rate_parent_fops = { 315 .open = simple_open, 316 .read = nsim_dev_rate_parent_read, 317 .llseek = generic_file_llseek, 318 .owner = THIS_MODULE, 319 }; 320 321 static void nsim_dev_tc_bw_debugfs_init(struct dentry *ddir, u32 *tc_bw) 322 { 323 int i; 324 325 for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) { 326 char name[16]; 327 328 snprintf(name, sizeof(name), "tc%d_bw", i); 329 debugfs_create_u32(name, 0400, ddir, &tc_bw[i]); 330 } 331 } 332 static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev, 333 struct nsim_dev_port *nsim_dev_port) 334 { 335 struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev; 336 unsigned int port_index = nsim_dev_port->port_index; 337 char port_ddir_name[16]; 338 char dev_link_name[32]; 339 340 sprintf(port_ddir_name, "%u", port_index); 341 nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name, 342 nsim_dev->ports_ddir); 343 if (IS_ERR(nsim_dev_port->ddir)) 344 return PTR_ERR(nsim_dev_port->ddir); 345 346 sprintf(dev_link_name, "../../../" DRV_NAME "%u", nsim_bus_dev->dev.id); 347 if (nsim_dev_port_is_vf(nsim_dev_port)) { 348 unsigned int vf_id = nsim_dev_port_index_to_vf_index(port_index); 349 350 debugfs_create_u16("tx_share", 0400, nsim_dev_port->ddir, 351 &nsim_dev->vfconfigs[vf_id].min_tx_rate); 352 debugfs_create_u16("tx_max", 0400, nsim_dev_port->ddir, 353 &nsim_dev->vfconfigs[vf_id].max_tx_rate); 354 nsim_dev_port->rate_parent = debugfs_create_file("rate_parent", 355 0400, 356 nsim_dev_port->ddir, 357 &nsim_dev_port->parent_name, 358 &nsim_dev_rate_parent_fops); 359 nsim_dev_tc_bw_debugfs_init(nsim_dev_port->ddir, 360 nsim_dev_port->tc_bw); 361 } 362 debugfs_create_symlink("dev", nsim_dev_port->ddir, dev_link_name); 363 364 return 0; 365 } 366 367 static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port) 368 { 369 debugfs_remove_recursive(nsim_dev_port->ddir); 370 } 371 372 static int nsim_dev_resources_register(struct devlink *devlink) 373 { 374 struct devlink_resource_size_params params = { 375 .size_max = (u64)-1, 376 .size_granularity = 1, 377 .unit = DEVLINK_RESOURCE_UNIT_ENTRY 378 }; 379 int err; 380 381 /* Resources for IPv4 */ 382 err = devl_resource_register(devlink, "IPv4", (u64)-1, 383 NSIM_RESOURCE_IPV4, 384 DEVLINK_RESOURCE_ID_PARENT_TOP, 385 ¶ms); 386 if (err) { 387 pr_err("Failed to register IPv4 top resource\n"); 388 goto err_out; 389 } 390 391 err = devl_resource_register(devlink, "fib", (u64)-1, 392 NSIM_RESOURCE_IPV4_FIB, 393 NSIM_RESOURCE_IPV4, ¶ms); 394 if (err) { 395 pr_err("Failed to register IPv4 FIB resource\n"); 396 goto err_out; 397 } 398 399 err = devl_resource_register(devlink, "fib-rules", (u64)-1, 400 NSIM_RESOURCE_IPV4_FIB_RULES, 401 NSIM_RESOURCE_IPV4, ¶ms); 402 if (err) { 403 pr_err("Failed to register IPv4 FIB rules resource\n"); 404 goto err_out; 405 } 406 407 /* Resources for IPv6 */ 408 err = devl_resource_register(devlink, "IPv6", (u64)-1, 409 NSIM_RESOURCE_IPV6, 410 DEVLINK_RESOURCE_ID_PARENT_TOP, 411 ¶ms); 412 if (err) { 413 pr_err("Failed to register IPv6 top resource\n"); 414 goto err_out; 415 } 416 417 err = devl_resource_register(devlink, "fib", (u64)-1, 418 NSIM_RESOURCE_IPV6_FIB, 419 NSIM_RESOURCE_IPV6, ¶ms); 420 if (err) { 421 pr_err("Failed to register IPv6 FIB resource\n"); 422 goto err_out; 423 } 424 425 err = devl_resource_register(devlink, "fib-rules", (u64)-1, 426 NSIM_RESOURCE_IPV6_FIB_RULES, 427 NSIM_RESOURCE_IPV6, ¶ms); 428 if (err) { 429 pr_err("Failed to register IPv6 FIB rules resource\n"); 430 goto err_out; 431 } 432 433 /* Resources for nexthops */ 434 err = devl_resource_register(devlink, "nexthops", (u64)-1, 435 NSIM_RESOURCE_NEXTHOPS, 436 DEVLINK_RESOURCE_ID_PARENT_TOP, 437 ¶ms); 438 if (err) { 439 pr_err("Failed to register NEXTHOPS resource\n"); 440 goto err_out; 441 } 442 return 0; 443 444 err_out: 445 devl_resources_unregister(devlink); 446 return err; 447 } 448 449 enum nsim_devlink_param_id { 450 NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 451 NSIM_DEVLINK_PARAM_ID_TEST1, 452 NSIM_DEVLINK_PARAM_ID_TEST2, 453 }; 454 455 static int 456 nsim_devlink_param_test2_get(struct devlink *devlink, u32 id, 457 struct devlink_param_gset_ctx *ctx, 458 struct netlink_ext_ack *extack) 459 { 460 struct nsim_dev *nsim_dev = devlink_priv(devlink); 461 462 ctx->val.vu32 = nsim_dev->test2; 463 return 0; 464 } 465 466 static int 467 nsim_devlink_param_test2_set(struct devlink *devlink, u32 id, 468 struct devlink_param_gset_ctx *ctx, 469 struct netlink_ext_ack *extack) 470 { 471 struct nsim_dev *nsim_dev = devlink_priv(devlink); 472 473 nsim_dev->test2 = ctx->val.vu32; 474 return 0; 475 } 476 477 #define NSIM_DEV_TEST2_DEFAULT 1234 478 479 static int 480 nsim_devlink_param_test2_get_default(struct devlink *devlink, u32 id, 481 struct devlink_param_gset_ctx *ctx, 482 struct netlink_ext_ack *extack) 483 { 484 ctx->val.vu32 = NSIM_DEV_TEST2_DEFAULT; 485 return 0; 486 } 487 488 static int 489 nsim_devlink_param_test2_reset_default(struct devlink *devlink, u32 id, 490 enum devlink_param_cmode cmode, 491 struct netlink_ext_ack *extack) 492 { 493 struct nsim_dev *nsim_dev = devlink_priv(devlink); 494 495 nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; 496 return 0; 497 } 498 499 static const struct devlink_param nsim_devlink_params[] = { 500 DEVLINK_PARAM_GENERIC(MAX_MACS, 501 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 502 NULL, NULL, NULL), 503 DEVLINK_PARAM_DRIVER(NSIM_DEVLINK_PARAM_ID_TEST1, 504 "test1", DEVLINK_PARAM_TYPE_BOOL, 505 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 506 NULL, NULL, NULL), 507 DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(NSIM_DEVLINK_PARAM_ID_TEST2, 508 "test2", DEVLINK_PARAM_TYPE_U32, 509 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 510 nsim_devlink_param_test2_get, 511 nsim_devlink_param_test2_set, 512 NULL, 513 nsim_devlink_param_test2_get_default, 514 nsim_devlink_param_test2_reset_default), 515 }; 516 517 static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev, 518 struct devlink *devlink) 519 { 520 union devlink_param_value value; 521 522 value.vu32 = nsim_dev->max_macs; 523 devl_param_driverinit_value_set(devlink, 524 DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 525 &value); 526 value.vbool = nsim_dev->test1; 527 devl_param_driverinit_value_set(devlink, 528 NSIM_DEVLINK_PARAM_ID_TEST1, 529 &value); 530 } 531 532 static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink) 533 { 534 struct nsim_dev *nsim_dev = devlink_priv(devlink); 535 union devlink_param_value saved_value; 536 int err; 537 538 err = devl_param_driverinit_value_get(devlink, 539 DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 540 &saved_value); 541 if (!err) 542 nsim_dev->max_macs = saved_value.vu32; 543 err = devl_param_driverinit_value_get(devlink, 544 NSIM_DEVLINK_PARAM_ID_TEST1, 545 &saved_value); 546 if (!err) 547 nsim_dev->test1 = saved_value.vbool; 548 } 549 550 #define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16 551 552 static const struct devlink_region_ops dummy_region_ops = { 553 .name = "dummy", 554 .destructor = &kfree, 555 .snapshot = nsim_dev_take_snapshot, 556 }; 557 558 static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev, 559 struct devlink *devlink) 560 { 561 nsim_dev->dummy_region = 562 devl_region_create(devlink, &dummy_region_ops, 563 NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX, 564 NSIM_DEV_DUMMY_REGION_SIZE); 565 return PTR_ERR_OR_ZERO(nsim_dev->dummy_region); 566 } 567 568 static void nsim_dev_dummy_region_exit(struct nsim_dev *nsim_dev) 569 { 570 devl_region_destroy(nsim_dev->dummy_region); 571 } 572 573 static int 574 __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, 575 unsigned int port_index, u8 perm_addr[ETH_ALEN]); 576 static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port); 577 578 static int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev, 579 struct netlink_ext_ack *extack) 580 { 581 struct devlink *devlink = priv_to_devlink(nsim_dev); 582 struct nsim_dev_port *nsim_dev_port, *tmp; 583 584 devl_rate_nodes_destroy(devlink); 585 list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) 586 if (nsim_dev_port_is_vf(nsim_dev_port)) 587 __nsim_dev_port_del(nsim_dev_port); 588 nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY; 589 return 0; 590 } 591 592 static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, 593 struct netlink_ext_ack *extack) 594 { 595 struct nsim_dev_port *nsim_dev_port, *tmp; 596 int i, err; 597 598 for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) { 599 err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_VF, i, NULL); 600 if (err) { 601 NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports"); 602 pr_err("Failed to initialize VF id=%d. %d.\n", i, err); 603 goto err_port_add_vfs; 604 } 605 } 606 nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV; 607 return 0; 608 609 err_port_add_vfs: 610 list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) 611 if (nsim_dev_port_is_vf(nsim_dev_port)) 612 __nsim_dev_port_del(nsim_dev_port); 613 return err; 614 } 615 616 static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, 617 struct netlink_ext_ack *extack) 618 { 619 struct nsim_dev *nsim_dev = devlink_priv(devlink); 620 621 if (mode == nsim_dev->esw_mode) 622 return 0; 623 624 if (mode == DEVLINK_ESWITCH_MODE_LEGACY) 625 return nsim_esw_legacy_enable(nsim_dev, extack); 626 if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) 627 return nsim_esw_switchdev_enable(nsim_dev, extack); 628 629 return -EINVAL; 630 } 631 632 static int nsim_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) 633 { 634 struct nsim_dev *nsim_dev = devlink_priv(devlink); 635 636 *mode = nsim_dev->esw_mode; 637 return 0; 638 } 639 640 struct nsim_trap_item { 641 void *trap_ctx; 642 enum devlink_trap_action action; 643 }; 644 645 struct nsim_trap_data { 646 struct delayed_work trap_report_dw; 647 struct nsim_trap_item *trap_items_arr; 648 u64 *trap_policers_cnt_arr; 649 u64 trap_pkt_cnt; 650 struct nsim_dev *nsim_dev; 651 spinlock_t trap_lock; /* Protects trap_items_arr */ 652 }; 653 654 /* All driver-specific traps must be documented in 655 * Documentation/networking/devlink/netdevsim.rst 656 */ 657 enum { 658 NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX, 659 NSIM_TRAP_ID_FID_MISS, 660 }; 661 662 #define NSIM_TRAP_NAME_FID_MISS "fid_miss" 663 664 #define NSIM_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT 665 666 #define NSIM_TRAP_DROP(_id, _group_id) \ 667 DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 668 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 669 NSIM_TRAP_METADATA) 670 #define NSIM_TRAP_DROP_EXT(_id, _group_id, _metadata) \ 671 DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 672 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 673 NSIM_TRAP_METADATA | (_metadata)) 674 #define NSIM_TRAP_EXCEPTION(_id, _group_id) \ 675 DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \ 676 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 677 NSIM_TRAP_METADATA) 678 #define NSIM_TRAP_CONTROL(_id, _group_id, _action) \ 679 DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \ 680 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 681 NSIM_TRAP_METADATA) 682 #define NSIM_TRAP_DRIVER_EXCEPTION(_id, _group_id) \ 683 DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, NSIM_TRAP_ID_##_id, \ 684 NSIM_TRAP_NAME_##_id, \ 685 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 686 NSIM_TRAP_METADATA) 687 688 #define NSIM_DEV_TRAP_POLICER_MIN_RATE 1 689 #define NSIM_DEV_TRAP_POLICER_MAX_RATE 8000 690 #define NSIM_DEV_TRAP_POLICER_MIN_BURST 8 691 #define NSIM_DEV_TRAP_POLICER_MAX_BURST 65536 692 693 #define NSIM_TRAP_POLICER(_id, _rate, _burst) \ 694 DEVLINK_TRAP_POLICER(_id, _rate, _burst, \ 695 NSIM_DEV_TRAP_POLICER_MAX_RATE, \ 696 NSIM_DEV_TRAP_POLICER_MIN_RATE, \ 697 NSIM_DEV_TRAP_POLICER_MAX_BURST, \ 698 NSIM_DEV_TRAP_POLICER_MIN_BURST) 699 700 static const struct devlink_trap_policer nsim_trap_policers_arr[] = { 701 NSIM_TRAP_POLICER(1, 1000, 128), 702 NSIM_TRAP_POLICER(2, 2000, 256), 703 NSIM_TRAP_POLICER(3, 3000, 512), 704 }; 705 706 static const struct devlink_trap_group nsim_trap_groups_arr[] = { 707 DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0), 708 DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1), 709 DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1), 710 DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 2), 711 DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 3), 712 DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 3), 713 }; 714 715 static const struct devlink_trap nsim_traps_arr[] = { 716 NSIM_TRAP_DROP(SMAC_MC, L2_DROPS), 717 NSIM_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS), 718 NSIM_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS), 719 NSIM_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS), 720 NSIM_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS), 721 NSIM_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS), 722 NSIM_TRAP_DRIVER_EXCEPTION(FID_MISS, L2_DROPS), 723 NSIM_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS), 724 NSIM_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS), 725 NSIM_TRAP_DROP(TAIL_DROP, BUFFER_DROPS), 726 NSIM_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, ACL_DROPS, 727 DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 728 NSIM_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, ACL_DROPS, 729 DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 730 NSIM_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR), 731 NSIM_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, TRAP), 732 }; 733 734 #define NSIM_TRAP_L4_DATA_LEN 100 735 736 static struct sk_buff *nsim_dev_trap_skb_build(void) 737 { 738 int tot_len, data_len = NSIM_TRAP_L4_DATA_LEN; 739 struct sk_buff *skb; 740 struct udphdr *udph; 741 struct ethhdr *eth; 742 struct iphdr *iph; 743 744 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 745 if (!skb) 746 return NULL; 747 tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len; 748 749 skb_reset_mac_header(skb); 750 eth = skb_put(skb, sizeof(struct ethhdr)); 751 eth_random_addr(eth->h_dest); 752 eth_random_addr(eth->h_source); 753 eth->h_proto = htons(ETH_P_IP); 754 skb->protocol = htons(ETH_P_IP); 755 756 skb_set_network_header(skb, skb->len); 757 iph = skb_put_zero(skb, sizeof(struct iphdr)); 758 iph->protocol = IPPROTO_UDP; 759 iph->saddr = in_aton("192.0.2.1"); 760 iph->daddr = in_aton("198.51.100.1"); 761 iph->version = 0x4; 762 iph->frag_off = 0; 763 iph->ihl = 0x5; 764 iph->tot_len = htons(tot_len); 765 iph->ttl = 100; 766 iph->check = 0; 767 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); 768 769 skb_set_transport_header(skb, skb->len); 770 udph = skb_put_zero(skb, sizeof(struct udphdr) + data_len); 771 get_random_bytes(&udph->source, sizeof(u16)); 772 get_random_bytes(&udph->dest, sizeof(u16)); 773 udp_set_len_short(udph, sizeof(struct udphdr) + data_len); 774 775 return skb; 776 } 777 778 static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port) 779 { 780 struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev; 781 struct devlink *devlink = priv_to_devlink(nsim_dev); 782 struct nsim_trap_data *nsim_trap_data; 783 int i; 784 785 nsim_trap_data = nsim_dev->trap_data; 786 787 spin_lock(&nsim_trap_data->trap_lock); 788 for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) { 789 struct flow_action_cookie *fa_cookie = NULL; 790 struct nsim_trap_item *nsim_trap_item; 791 struct sk_buff *skb; 792 bool has_fa_cookie; 793 794 has_fa_cookie = nsim_traps_arr[i].metadata_cap & 795 DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE; 796 797 nsim_trap_item = &nsim_trap_data->trap_items_arr[i]; 798 if (nsim_trap_item->action == DEVLINK_TRAP_ACTION_DROP) 799 continue; 800 801 skb = nsim_dev_trap_skb_build(); 802 if (!skb) 803 continue; 804 skb->dev = nsim_dev_port->ns->netdev; 805 806 /* Trapped packets are usually passed to devlink in softIRQ, 807 * but in this case they are generated in a workqueue. Disable 808 * softIRQs to prevent lockdep from complaining about 809 * "incosistent lock state". 810 */ 811 812 spin_lock_bh(&nsim_dev->fa_cookie_lock); 813 fa_cookie = has_fa_cookie ? nsim_dev->fa_cookie : NULL; 814 devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx, 815 &nsim_dev_port->devlink_port, fa_cookie); 816 spin_unlock_bh(&nsim_dev->fa_cookie_lock); 817 consume_skb(skb); 818 } 819 spin_unlock(&nsim_trap_data->trap_lock); 820 } 821 822 #define NSIM_TRAP_REPORT_INTERVAL_MS 100 823 824 static void nsim_dev_trap_report_work(struct work_struct *work) 825 { 826 struct nsim_trap_data *nsim_trap_data; 827 struct nsim_dev_port *nsim_dev_port; 828 struct nsim_dev *nsim_dev; 829 830 nsim_trap_data = container_of(work, struct nsim_trap_data, 831 trap_report_dw.work); 832 nsim_dev = nsim_trap_data->nsim_dev; 833 834 if (!devl_trylock(priv_to_devlink(nsim_dev))) { 835 queue_delayed_work(system_dfl_wq, 836 &nsim_dev->trap_data->trap_report_dw, 1); 837 return; 838 } 839 840 /* For each running port and enabled packet trap, generate a UDP 841 * packet with a random 5-tuple and report it. 842 */ 843 list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) { 844 if (!netif_running(nsim_dev_port->ns->netdev)) 845 continue; 846 847 nsim_dev_trap_report(nsim_dev_port); 848 cond_resched(); 849 } 850 devl_unlock(priv_to_devlink(nsim_dev)); 851 queue_delayed_work(system_dfl_wq, 852 &nsim_dev->trap_data->trap_report_dw, 853 msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); 854 } 855 856 static int nsim_dev_traps_init(struct devlink *devlink) 857 { 858 size_t policers_count = ARRAY_SIZE(nsim_trap_policers_arr); 859 struct nsim_dev *nsim_dev = devlink_priv(devlink); 860 struct nsim_trap_data *nsim_trap_data; 861 int err; 862 863 nsim_trap_data = kzalloc_obj(*nsim_trap_data); 864 if (!nsim_trap_data) 865 return -ENOMEM; 866 867 nsim_trap_data->trap_items_arr = kzalloc_objs(struct nsim_trap_item, 868 ARRAY_SIZE(nsim_traps_arr)); 869 if (!nsim_trap_data->trap_items_arr) { 870 err = -ENOMEM; 871 goto err_trap_data_free; 872 } 873 874 nsim_trap_data->trap_policers_cnt_arr = kcalloc(policers_count, 875 sizeof(u64), 876 GFP_KERNEL); 877 if (!nsim_trap_data->trap_policers_cnt_arr) { 878 err = -ENOMEM; 879 goto err_trap_items_free; 880 } 881 882 /* The lock is used to protect the action state of the registered 883 * traps. The value is written by user and read in delayed work when 884 * iterating over all the traps. 885 */ 886 spin_lock_init(&nsim_trap_data->trap_lock); 887 nsim_trap_data->nsim_dev = nsim_dev; 888 nsim_dev->trap_data = nsim_trap_data; 889 890 err = devl_trap_policers_register(devlink, nsim_trap_policers_arr, 891 policers_count); 892 if (err) 893 goto err_trap_policers_cnt_free; 894 895 err = devl_trap_groups_register(devlink, nsim_trap_groups_arr, 896 ARRAY_SIZE(nsim_trap_groups_arr)); 897 if (err) 898 goto err_trap_policers_unregister; 899 900 err = devl_traps_register(devlink, nsim_traps_arr, 901 ARRAY_SIZE(nsim_traps_arr), NULL); 902 if (err) 903 goto err_trap_groups_unregister; 904 905 INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, 906 nsim_dev_trap_report_work); 907 queue_delayed_work(system_dfl_wq, 908 &nsim_dev->trap_data->trap_report_dw, 909 msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); 910 911 return 0; 912 913 err_trap_groups_unregister: 914 devl_trap_groups_unregister(devlink, nsim_trap_groups_arr, 915 ARRAY_SIZE(nsim_trap_groups_arr)); 916 err_trap_policers_unregister: 917 devl_trap_policers_unregister(devlink, nsim_trap_policers_arr, 918 ARRAY_SIZE(nsim_trap_policers_arr)); 919 err_trap_policers_cnt_free: 920 kfree(nsim_trap_data->trap_policers_cnt_arr); 921 err_trap_items_free: 922 kfree(nsim_trap_data->trap_items_arr); 923 err_trap_data_free: 924 kfree(nsim_trap_data); 925 return err; 926 } 927 928 static void nsim_dev_traps_exit(struct devlink *devlink) 929 { 930 struct nsim_dev *nsim_dev = devlink_priv(devlink); 931 932 /* caution, trap work takes devlink lock */ 933 cancel_delayed_work_sync(&nsim_dev->trap_data->trap_report_dw); 934 devl_traps_unregister(devlink, nsim_traps_arr, 935 ARRAY_SIZE(nsim_traps_arr)); 936 devl_trap_groups_unregister(devlink, nsim_trap_groups_arr, 937 ARRAY_SIZE(nsim_trap_groups_arr)); 938 devl_trap_policers_unregister(devlink, nsim_trap_policers_arr, 939 ARRAY_SIZE(nsim_trap_policers_arr)); 940 kfree(nsim_dev->trap_data->trap_policers_cnt_arr); 941 kfree(nsim_dev->trap_data->trap_items_arr); 942 kfree(nsim_dev->trap_data); 943 } 944 945 static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, 946 struct netlink_ext_ack *extack); 947 static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev); 948 949 static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change, 950 enum devlink_reload_action action, enum devlink_reload_limit limit, 951 struct netlink_ext_ack *extack) 952 { 953 struct nsim_dev *nsim_dev = devlink_priv(devlink); 954 955 if (nsim_dev->dont_allow_reload) { 956 /* For testing purposes, user set debugfs dont_allow_reload 957 * value to true. So forbid it. 958 */ 959 NL_SET_ERR_MSG_MOD(extack, "User forbid the reload for testing purposes"); 960 return -EOPNOTSUPP; 961 } 962 963 nsim_dev_reload_destroy(nsim_dev); 964 return 0; 965 } 966 967 static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action, 968 enum devlink_reload_limit limit, u32 *actions_performed, 969 struct netlink_ext_ack *extack) 970 { 971 struct nsim_dev *nsim_dev = devlink_priv(devlink); 972 973 if (nsim_dev->fail_reload) { 974 /* For testing purposes, user set debugfs fail_reload 975 * value to true. Fail right away. 976 */ 977 NL_SET_ERR_MSG_MOD(extack, "User setup the reload to fail for testing purposes"); 978 return -EINVAL; 979 } 980 981 *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 982 983 return nsim_dev_reload_create(nsim_dev, extack); 984 } 985 986 static int nsim_dev_info_get(struct devlink *devlink, 987 struct devlink_info_req *req, 988 struct netlink_ext_ack *extack) 989 { 990 int err; 991 992 err = devlink_info_version_stored_put_ext(req, "fw.mgmt", "10.20.30", 993 DEVLINK_INFO_VERSION_TYPE_COMPONENT); 994 if (err) 995 return err; 996 return devlink_info_version_running_put_ext(req, "fw.mgmt", "10.20.30", 997 DEVLINK_INFO_VERSION_TYPE_COMPONENT); 998 } 999 1000 #define NSIM_DEV_FLASH_SIZE 50000 1001 #define NSIM_DEV_FLASH_CHUNK_SIZE 1000 1002 #define NSIM_DEV_FLASH_CHUNK_TIME_MS_DEFAULT 100 1003 1004 static int nsim_dev_flash_update(struct devlink *devlink, 1005 struct devlink_flash_update_params *params, 1006 struct netlink_ext_ack *extack) 1007 { 1008 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1009 int i; 1010 1011 if ((params->overwrite_mask & ~nsim_dev->fw_update_overwrite_mask) != 0) 1012 return -EOPNOTSUPP; 1013 1014 if (nsim_dev->fw_update_status) { 1015 devlink_flash_update_status_notify(devlink, 1016 "Preparing to flash", 1017 params->component, 0, 0); 1018 } 1019 1020 for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) { 1021 if (nsim_dev->fw_update_status) 1022 devlink_flash_update_status_notify(devlink, "Flashing", 1023 params->component, 1024 i * NSIM_DEV_FLASH_CHUNK_SIZE, 1025 NSIM_DEV_FLASH_SIZE); 1026 msleep(nsim_dev->fw_update_flash_chunk_time_ms ?: 1); 1027 } 1028 1029 if (nsim_dev->fw_update_status) { 1030 devlink_flash_update_status_notify(devlink, "Flashing", 1031 params->component, 1032 NSIM_DEV_FLASH_SIZE, 1033 NSIM_DEV_FLASH_SIZE); 1034 devlink_flash_update_timeout_notify(devlink, "Flash select", 1035 params->component, 81); 1036 devlink_flash_update_status_notify(devlink, "Flashing done", 1037 params->component, 0, 0); 1038 } 1039 1040 return 0; 1041 } 1042 1043 static struct nsim_trap_item * 1044 nsim_dev_trap_item_lookup(struct nsim_dev *nsim_dev, u16 trap_id) 1045 { 1046 struct nsim_trap_data *nsim_trap_data = nsim_dev->trap_data; 1047 int i; 1048 1049 for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) { 1050 if (nsim_traps_arr[i].id == trap_id) 1051 return &nsim_trap_data->trap_items_arr[i]; 1052 } 1053 1054 return NULL; 1055 } 1056 1057 static int nsim_dev_devlink_trap_init(struct devlink *devlink, 1058 const struct devlink_trap *trap, 1059 void *trap_ctx) 1060 { 1061 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1062 struct nsim_trap_item *nsim_trap_item; 1063 1064 nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id); 1065 if (WARN_ON(!nsim_trap_item)) 1066 return -ENOENT; 1067 1068 nsim_trap_item->trap_ctx = trap_ctx; 1069 nsim_trap_item->action = trap->init_action; 1070 1071 return 0; 1072 } 1073 1074 static int 1075 nsim_dev_devlink_trap_action_set(struct devlink *devlink, 1076 const struct devlink_trap *trap, 1077 enum devlink_trap_action action, 1078 struct netlink_ext_ack *extack) 1079 { 1080 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1081 struct nsim_trap_item *nsim_trap_item; 1082 1083 nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id); 1084 if (WARN_ON(!nsim_trap_item)) 1085 return -ENOENT; 1086 1087 spin_lock(&nsim_dev->trap_data->trap_lock); 1088 nsim_trap_item->action = action; 1089 spin_unlock(&nsim_dev->trap_data->trap_lock); 1090 1091 return 0; 1092 } 1093 1094 static int 1095 nsim_dev_devlink_trap_group_set(struct devlink *devlink, 1096 const struct devlink_trap_group *group, 1097 const struct devlink_trap_policer *policer, 1098 struct netlink_ext_ack *extack) 1099 { 1100 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1101 1102 if (nsim_dev->fail_trap_group_set) 1103 return -EINVAL; 1104 1105 return 0; 1106 } 1107 1108 static int 1109 nsim_dev_devlink_trap_policer_set(struct devlink *devlink, 1110 const struct devlink_trap_policer *policer, 1111 u64 rate, u64 burst, 1112 struct netlink_ext_ack *extack) 1113 { 1114 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1115 1116 if (nsim_dev->fail_trap_policer_set) { 1117 NL_SET_ERR_MSG_MOD(extack, "User setup the operation to fail for testing purposes"); 1118 return -EINVAL; 1119 } 1120 1121 return 0; 1122 } 1123 1124 static int 1125 nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink, 1126 const struct devlink_trap_policer *policer, 1127 u64 *p_drops) 1128 { 1129 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1130 u64 *cnt; 1131 1132 if (nsim_dev->fail_trap_policer_counter_get) 1133 return -EINVAL; 1134 1135 cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1]; 1136 *p_drops = (*cnt)++; 1137 1138 return 0; 1139 } 1140 1141 #define NSIM_LINK_SPEED_MAX 5000 /* Mbps */ 1142 #define NSIM_LINK_SPEED_UNIT 125000 /* 1 Mbps given in bytes/sec to avoid 1143 * u64 overflow during conversion from 1144 * bytes to bits. 1145 */ 1146 1147 static int nsim_rate_bytes_to_units(char *name, u64 *rate, struct netlink_ext_ack *extack) 1148 { 1149 u64 val; 1150 u32 rem; 1151 1152 val = div_u64_rem(*rate, NSIM_LINK_SPEED_UNIT, &rem); 1153 if (rem) { 1154 pr_err("%s rate value %lluBps not in link speed units of 1Mbps.\n", 1155 name, *rate); 1156 NL_SET_ERR_MSG_MOD(extack, "TX rate value not in link speed units of 1Mbps."); 1157 return -EINVAL; 1158 } 1159 1160 if (val > NSIM_LINK_SPEED_MAX) { 1161 pr_err("%s rate value %lluMbps exceed link maximum speed 5000Mbps.\n", 1162 name, val); 1163 NL_SET_ERR_MSG_MOD(extack, "TX rate value exceed link maximum speed 5000Mbps."); 1164 return -EINVAL; 1165 } 1166 *rate = val; 1167 return 0; 1168 } 1169 1170 static int nsim_leaf_tc_bw_set(struct devlink_rate *devlink_rate, 1171 void *priv, u32 *tc_bw, 1172 struct netlink_ext_ack *extack) 1173 { 1174 struct nsim_dev_port *nsim_dev_port = priv; 1175 int i; 1176 1177 for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) 1178 nsim_dev_port->tc_bw[i] = tc_bw[i]; 1179 1180 return 0; 1181 } 1182 1183 static int nsim_leaf_tx_share_set(struct devlink_rate *devlink_rate, void *priv, 1184 u64 tx_share, struct netlink_ext_ack *extack) 1185 { 1186 struct nsim_dev_port *nsim_dev_port = priv; 1187 struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev; 1188 int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index); 1189 int err; 1190 1191 err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack); 1192 if (err) 1193 return err; 1194 1195 nsim_dev->vfconfigs[vf_id].min_tx_rate = tx_share; 1196 return 0; 1197 } 1198 1199 static int nsim_leaf_tx_max_set(struct devlink_rate *devlink_rate, void *priv, 1200 u64 tx_max, struct netlink_ext_ack *extack) 1201 { 1202 struct nsim_dev_port *nsim_dev_port = priv; 1203 struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev; 1204 int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index); 1205 int err; 1206 1207 err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack); 1208 if (err) 1209 return err; 1210 1211 nsim_dev->vfconfigs[vf_id].max_tx_rate = tx_max; 1212 return 0; 1213 } 1214 1215 struct nsim_rate_node { 1216 struct dentry *ddir; 1217 struct dentry *rate_parent; 1218 char *parent_name; 1219 u16 tx_share; 1220 u16 tx_max; 1221 u32 tc_bw[DEVLINK_RATE_TCS_MAX]; 1222 }; 1223 1224 static int nsim_node_tc_bw_set(struct devlink_rate *devlink_rate, void *priv, 1225 u32 *tc_bw, struct netlink_ext_ack *extack) 1226 { 1227 struct nsim_rate_node *nsim_node = priv; 1228 int i; 1229 1230 for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) 1231 nsim_node->tc_bw[i] = tc_bw[i]; 1232 1233 return 0; 1234 } 1235 1236 static int nsim_node_tx_share_set(struct devlink_rate *devlink_rate, void *priv, 1237 u64 tx_share, struct netlink_ext_ack *extack) 1238 { 1239 struct nsim_rate_node *nsim_node = priv; 1240 int err; 1241 1242 err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack); 1243 if (err) 1244 return err; 1245 1246 nsim_node->tx_share = tx_share; 1247 return 0; 1248 } 1249 1250 static int nsim_node_tx_max_set(struct devlink_rate *devlink_rate, void *priv, 1251 u64 tx_max, struct netlink_ext_ack *extack) 1252 { 1253 struct nsim_rate_node *nsim_node = priv; 1254 int err; 1255 1256 err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack); 1257 if (err) 1258 return err; 1259 1260 nsim_node->tx_max = tx_max; 1261 return 0; 1262 } 1263 1264 static int nsim_rate_node_new(struct devlink_rate *node, void **priv, 1265 struct netlink_ext_ack *extack) 1266 { 1267 struct nsim_dev *nsim_dev = devlink_priv(node->devlink); 1268 struct nsim_rate_node *nsim_node; 1269 1270 if (!nsim_esw_mode_is_switchdev(nsim_dev)) { 1271 NL_SET_ERR_MSG_MOD(extack, "Node creation allowed only in switchdev mode."); 1272 return -EOPNOTSUPP; 1273 } 1274 1275 nsim_node = kzalloc_obj(*nsim_node); 1276 if (!nsim_node) 1277 return -ENOMEM; 1278 1279 nsim_node->ddir = debugfs_create_dir(node->name, nsim_dev->nodes_ddir); 1280 1281 debugfs_create_u16("tx_share", 0400, nsim_node->ddir, &nsim_node->tx_share); 1282 debugfs_create_u16("tx_max", 0400, nsim_node->ddir, &nsim_node->tx_max); 1283 nsim_node->rate_parent = debugfs_create_file("rate_parent", 0400, 1284 nsim_node->ddir, 1285 &nsim_node->parent_name, 1286 &nsim_dev_rate_parent_fops); 1287 1288 nsim_dev_tc_bw_debugfs_init(nsim_node->ddir, nsim_node->tc_bw); 1289 1290 *priv = nsim_node; 1291 return 0; 1292 } 1293 1294 static int nsim_rate_node_del(struct devlink_rate *node, void *priv, 1295 struct netlink_ext_ack *extack) 1296 { 1297 struct nsim_rate_node *nsim_node = priv; 1298 1299 debugfs_remove(nsim_node->rate_parent); 1300 debugfs_remove_recursive(nsim_node->ddir); 1301 kfree(nsim_node); 1302 return 0; 1303 } 1304 1305 static int nsim_rate_leaf_parent_set(struct devlink_rate *child, 1306 struct devlink_rate *parent, 1307 void *priv_child, void *priv_parent, 1308 struct netlink_ext_ack *extack) 1309 { 1310 struct nsim_dev_port *nsim_dev_port = priv_child; 1311 1312 if (parent) 1313 nsim_dev_port->parent_name = parent->name; 1314 else 1315 nsim_dev_port->parent_name = NULL; 1316 return 0; 1317 } 1318 1319 static int nsim_rate_node_parent_set(struct devlink_rate *child, 1320 struct devlink_rate *parent, 1321 void *priv_child, void *priv_parent, 1322 struct netlink_ext_ack *extack) 1323 { 1324 struct nsim_rate_node *nsim_node = priv_child; 1325 1326 if (parent) 1327 nsim_node->parent_name = parent->name; 1328 else 1329 nsim_node->parent_name = NULL; 1330 return 0; 1331 } 1332 1333 static int 1334 nsim_dev_devlink_trap_drop_counter_get(struct devlink *devlink, 1335 const struct devlink_trap *trap, 1336 u64 *p_drops) 1337 { 1338 struct nsim_dev *nsim_dev = devlink_priv(devlink); 1339 u64 *cnt; 1340 1341 if (nsim_dev->fail_trap_drop_counter_get) 1342 return -EINVAL; 1343 1344 cnt = &nsim_dev->trap_data->trap_pkt_cnt; 1345 *p_drops = (*cnt)++; 1346 1347 return 0; 1348 } 1349 1350 static const struct devlink_ops nsim_dev_devlink_ops = { 1351 .eswitch_mode_set = nsim_devlink_eswitch_mode_set, 1352 .eswitch_mode_get = nsim_devlink_eswitch_mode_get, 1353 .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, 1354 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), 1355 .reload_down = nsim_dev_reload_down, 1356 .reload_up = nsim_dev_reload_up, 1357 .info_get = nsim_dev_info_get, 1358 .flash_update = nsim_dev_flash_update, 1359 .trap_init = nsim_dev_devlink_trap_init, 1360 .trap_action_set = nsim_dev_devlink_trap_action_set, 1361 .trap_group_set = nsim_dev_devlink_trap_group_set, 1362 .trap_policer_set = nsim_dev_devlink_trap_policer_set, 1363 .trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get, 1364 .rate_leaf_tx_share_set = nsim_leaf_tx_share_set, 1365 .rate_leaf_tx_max_set = nsim_leaf_tx_max_set, 1366 .rate_leaf_tc_bw_set = nsim_leaf_tc_bw_set, 1367 .rate_node_tx_share_set = nsim_node_tx_share_set, 1368 .rate_node_tx_max_set = nsim_node_tx_max_set, 1369 .rate_node_tc_bw_set = nsim_node_tc_bw_set, 1370 .rate_node_new = nsim_rate_node_new, 1371 .rate_node_del = nsim_rate_node_del, 1372 .rate_leaf_parent_set = nsim_rate_leaf_parent_set, 1373 .rate_node_parent_set = nsim_rate_node_parent_set, 1374 .trap_drop_counter_get = nsim_dev_devlink_trap_drop_counter_get, 1375 }; 1376 1377 #define NSIM_DEV_MAX_MACS_DEFAULT 32 1378 #define NSIM_DEV_TEST1_DEFAULT true 1379 1380 static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, 1381 unsigned int port_index, u8 perm_addr[ETH_ALEN]) 1382 { 1383 struct devlink_port_attrs attrs = {}; 1384 struct nsim_dev_port *nsim_dev_port; 1385 struct devlink_port *devlink_port; 1386 int err; 1387 1388 if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_dev_get_vfs(nsim_dev)) 1389 return -EINVAL; 1390 1391 nsim_dev_port = kzalloc_obj(*nsim_dev_port); 1392 if (!nsim_dev_port) 1393 return -ENOMEM; 1394 nsim_dev_port->port_index = nsim_dev_port_index(type, port_index); 1395 nsim_dev_port->port_type = type; 1396 1397 devlink_port = &nsim_dev_port->devlink_port; 1398 if (nsim_dev_port_is_pf(nsim_dev_port)) { 1399 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 1400 attrs.phys.port_number = port_index + 1; 1401 } else { 1402 attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF; 1403 attrs.pci_vf.pf = 0; 1404 attrs.pci_vf.vf = port_index; 1405 } 1406 memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); 1407 attrs.switch_id.id_len = nsim_dev->switch_id.id_len; 1408 devlink_port_attrs_set(devlink_port, &attrs); 1409 err = devl_port_register(priv_to_devlink(nsim_dev), devlink_port, 1410 nsim_dev_port->port_index); 1411 if (err) 1412 goto err_port_free; 1413 1414 if (nsim_dev_port_is_pf(nsim_dev_port)) { 1415 u64 parent_id = DEVLINK_RESOURCE_ID_PARENT_TOP; 1416 struct devlink_resource_size_params params = { 1417 .size_max = 100, 1418 .size_granularity = 1, 1419 .unit = DEVLINK_RESOURCE_UNIT_ENTRY 1420 }; 1421 1422 err = devl_port_resource_register(devlink_port, 1423 "test_resource", 20, 1424 NSIM_PORT_RESOURCE_TEST, 1425 parent_id, ¶ms); 1426 if (err) 1427 goto err_dl_port_unregister; 1428 } 1429 1430 err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port); 1431 if (err) 1432 goto err_port_resource_unregister; 1433 1434 nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port, perm_addr); 1435 if (IS_ERR(nsim_dev_port->ns)) { 1436 err = PTR_ERR(nsim_dev_port->ns); 1437 goto err_port_debugfs_exit; 1438 } 1439 1440 if (nsim_dev_port_is_vf(nsim_dev_port)) { 1441 err = devl_rate_leaf_create(&nsim_dev_port->devlink_port, 1442 nsim_dev_port, NULL); 1443 if (err) 1444 goto err_nsim_destroy; 1445 } 1446 1447 list_add(&nsim_dev_port->list, &nsim_dev->port_list); 1448 1449 return 0; 1450 1451 err_nsim_destroy: 1452 nsim_destroy(nsim_dev_port->ns); 1453 err_port_debugfs_exit: 1454 nsim_dev_port_debugfs_exit(nsim_dev_port); 1455 err_port_resource_unregister: 1456 if (nsim_dev_port_is_pf(nsim_dev_port)) 1457 devl_port_resources_unregister(devlink_port); 1458 err_dl_port_unregister: 1459 devl_port_unregister(devlink_port); 1460 err_port_free: 1461 kfree(nsim_dev_port); 1462 return err; 1463 } 1464 1465 static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port) 1466 { 1467 struct devlink_port *devlink_port = &nsim_dev_port->devlink_port; 1468 1469 list_del(&nsim_dev_port->list); 1470 if (nsim_dev_port_is_vf(nsim_dev_port)) 1471 devl_rate_leaf_destroy(&nsim_dev_port->devlink_port); 1472 nsim_destroy(nsim_dev_port->ns); 1473 nsim_dev_port_debugfs_exit(nsim_dev_port); 1474 if (nsim_dev_port_is_pf(nsim_dev_port)) 1475 devl_port_resources_unregister(devlink_port); 1476 devl_port_unregister(devlink_port); 1477 kfree(nsim_dev_port); 1478 } 1479 1480 static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev) 1481 { 1482 struct nsim_dev_port *nsim_dev_port, *tmp; 1483 1484 list_for_each_entry_safe(nsim_dev_port, tmp, 1485 &nsim_dev->port_list, list) 1486 __nsim_dev_port_del(nsim_dev_port); 1487 } 1488 1489 static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev, 1490 unsigned int port_count) 1491 { 1492 int i, err; 1493 1494 for (i = 0; i < port_count; i++) { 1495 err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_PF, i, NULL); 1496 if (err) 1497 goto err_port_del_all; 1498 } 1499 return 0; 1500 1501 err_port_del_all: 1502 nsim_dev_port_del_all(nsim_dev); 1503 return err; 1504 } 1505 1506 static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, 1507 struct netlink_ext_ack *extack) 1508 { 1509 struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev; 1510 struct devlink *devlink; 1511 int err; 1512 1513 devlink = priv_to_devlink(nsim_dev); 1514 nsim_dev = devlink_priv(devlink); 1515 INIT_LIST_HEAD(&nsim_dev->port_list); 1516 nsim_dev->fw_update_status = true; 1517 nsim_dev->fw_update_overwrite_mask = 0; 1518 1519 nsim_devlink_param_load_driverinit_values(devlink); 1520 1521 err = nsim_dev_dummy_region_init(nsim_dev, devlink); 1522 if (err) 1523 return err; 1524 1525 err = nsim_dev_traps_init(devlink); 1526 if (err) 1527 goto err_dummy_region_exit; 1528 1529 nsim_dev->fib_data = nsim_fib_create(devlink, extack); 1530 if (IS_ERR(nsim_dev->fib_data)) { 1531 err = PTR_ERR(nsim_dev->fib_data); 1532 goto err_traps_exit; 1533 } 1534 1535 err = nsim_dev_health_init(nsim_dev, devlink); 1536 if (err) 1537 goto err_fib_destroy; 1538 1539 err = nsim_dev_psample_init(nsim_dev); 1540 if (err) 1541 goto err_health_exit; 1542 1543 err = nsim_dev_hwstats_init(nsim_dev); 1544 if (err) 1545 goto err_psample_exit; 1546 1547 err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); 1548 if (err) 1549 goto err_hwstats_exit; 1550 1551 nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 1552 0200, 1553 nsim_dev->ddir, 1554 nsim_dev, 1555 &nsim_dev_take_snapshot_fops); 1556 return 0; 1557 1558 err_hwstats_exit: 1559 nsim_dev_hwstats_exit(nsim_dev); 1560 err_psample_exit: 1561 nsim_dev_psample_exit(nsim_dev); 1562 err_health_exit: 1563 nsim_dev_health_exit(nsim_dev); 1564 err_fib_destroy: 1565 nsim_fib_destroy(devlink, nsim_dev->fib_data); 1566 err_traps_exit: 1567 nsim_dev_traps_exit(devlink); 1568 err_dummy_region_exit: 1569 nsim_dev_dummy_region_exit(nsim_dev); 1570 return err; 1571 } 1572 1573 int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) 1574 { 1575 struct nsim_dev *nsim_dev; 1576 struct devlink *devlink; 1577 int err; 1578 1579 devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev), 1580 nsim_bus_dev->initial_net, &nsim_bus_dev->dev); 1581 if (!devlink) 1582 return -ENOMEM; 1583 devl_lock(devlink); 1584 nsim_dev = devlink_priv(devlink); 1585 nsim_dev->nsim_bus_dev = nsim_bus_dev; 1586 nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id); 1587 get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); 1588 INIT_LIST_HEAD(&nsim_dev->port_list); 1589 nsim_dev->fw_update_status = true; 1590 nsim_dev->fw_update_overwrite_mask = 0; 1591 nsim_dev->fw_update_flash_chunk_time_ms = NSIM_DEV_FLASH_CHUNK_TIME_MS_DEFAULT; 1592 nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; 1593 nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; 1594 nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; 1595 spin_lock_init(&nsim_dev->fa_cookie_lock); 1596 mutex_init(&nsim_dev->progs_list_lock); 1597 1598 dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); 1599 1600 nsim_dev->vfconfigs = kzalloc_objs(struct nsim_vf_config, 1601 NSIM_BUS_DEV_MAX_VFS, 1602 GFP_KERNEL | __GFP_NOWARN); 1603 if (!nsim_dev->vfconfigs) { 1604 err = -ENOMEM; 1605 goto err_devlink_unlock; 1606 } 1607 1608 err = devl_register(devlink); 1609 if (err) 1610 goto err_vfc_free; 1611 1612 err = nsim_dev_resources_register(devlink); 1613 if (err) 1614 goto err_dl_unregister; 1615 1616 err = devl_params_register(devlink, nsim_devlink_params, 1617 ARRAY_SIZE(nsim_devlink_params)); 1618 if (err) 1619 goto err_resource_unregister; 1620 nsim_devlink_set_params_init_values(nsim_dev, devlink); 1621 1622 err = nsim_dev_dummy_region_init(nsim_dev, devlink); 1623 if (err) 1624 goto err_params_unregister; 1625 1626 err = nsim_dev_traps_init(devlink); 1627 if (err) 1628 goto err_dummy_region_exit; 1629 1630 err = nsim_dev_debugfs_init(nsim_dev); 1631 if (err) 1632 goto err_traps_exit; 1633 1634 nsim_dev->fib_data = nsim_fib_create(devlink, NULL); 1635 if (IS_ERR(nsim_dev->fib_data)) { 1636 err = PTR_ERR(nsim_dev->fib_data); 1637 goto err_debugfs_exit; 1638 } 1639 1640 err = nsim_dev_health_init(nsim_dev, devlink); 1641 if (err) 1642 goto err_fib_destroy; 1643 1644 err = nsim_bpf_dev_init(nsim_dev); 1645 if (err) 1646 goto err_health_exit; 1647 1648 err = nsim_dev_psample_init(nsim_dev); 1649 if (err) 1650 goto err_bpf_dev_exit; 1651 1652 err = nsim_dev_hwstats_init(nsim_dev); 1653 if (err) 1654 goto err_psample_exit; 1655 1656 err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); 1657 if (err) 1658 goto err_hwstats_exit; 1659 1660 nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY; 1661 devl_unlock(devlink); 1662 return 0; 1663 1664 err_hwstats_exit: 1665 nsim_dev_hwstats_exit(nsim_dev); 1666 err_psample_exit: 1667 nsim_dev_psample_exit(nsim_dev); 1668 err_bpf_dev_exit: 1669 nsim_bpf_dev_exit(nsim_dev); 1670 err_health_exit: 1671 nsim_dev_health_exit(nsim_dev); 1672 err_fib_destroy: 1673 nsim_fib_destroy(devlink, nsim_dev->fib_data); 1674 err_debugfs_exit: 1675 nsim_dev_debugfs_exit(nsim_dev); 1676 err_traps_exit: 1677 nsim_dev_traps_exit(devlink); 1678 err_dummy_region_exit: 1679 nsim_dev_dummy_region_exit(nsim_dev); 1680 err_params_unregister: 1681 devl_params_unregister(devlink, nsim_devlink_params, 1682 ARRAY_SIZE(nsim_devlink_params)); 1683 err_resource_unregister: 1684 devl_resources_unregister(devlink); 1685 err_dl_unregister: 1686 devl_unregister(devlink); 1687 err_vfc_free: 1688 kfree(nsim_dev->vfconfigs); 1689 err_devlink_unlock: 1690 devl_unlock(devlink); 1691 devlink_free(devlink); 1692 dev_set_drvdata(&nsim_bus_dev->dev, NULL); 1693 return err; 1694 } 1695 1696 static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) 1697 { 1698 struct devlink *devlink = priv_to_devlink(nsim_dev); 1699 1700 if (devlink_is_reload_failed(devlink)) 1701 return; 1702 debugfs_remove(nsim_dev->take_snapshot); 1703 1704 if (nsim_dev_get_vfs(nsim_dev)) { 1705 nsim_bus_dev_set_vfs(nsim_dev->nsim_bus_dev, 0); 1706 if (nsim_esw_mode_is_switchdev(nsim_dev)) 1707 nsim_esw_legacy_enable(nsim_dev, NULL); 1708 } 1709 1710 nsim_dev_port_del_all(nsim_dev); 1711 nsim_dev_hwstats_exit(nsim_dev); 1712 nsim_dev_psample_exit(nsim_dev); 1713 nsim_dev_health_exit(nsim_dev); 1714 nsim_fib_destroy(devlink, nsim_dev->fib_data); 1715 nsim_dev_traps_exit(devlink); 1716 nsim_dev_dummy_region_exit(nsim_dev); 1717 } 1718 1719 void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev) 1720 { 1721 struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); 1722 struct devlink *devlink = priv_to_devlink(nsim_dev); 1723 1724 devl_lock(devlink); 1725 nsim_dev_reload_destroy(nsim_dev); 1726 1727 nsim_bpf_dev_exit(nsim_dev); 1728 nsim_dev_debugfs_exit(nsim_dev); 1729 devl_params_unregister(devlink, nsim_devlink_params, 1730 ARRAY_SIZE(nsim_devlink_params)); 1731 devl_resources_unregister(devlink); 1732 devl_unregister(devlink); 1733 kfree(nsim_dev->vfconfigs); 1734 kfree(nsim_dev->fa_cookie); 1735 mutex_destroy(&nsim_dev->progs_list_lock); 1736 devl_unlock(devlink); 1737 devlink_free(devlink); 1738 dev_set_drvdata(&nsim_bus_dev->dev, NULL); 1739 } 1740 1741 static struct nsim_dev_port * 1742 __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, 1743 unsigned int port_index) 1744 { 1745 struct nsim_dev_port *nsim_dev_port; 1746 1747 port_index = nsim_dev_port_index(type, port_index); 1748 list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) 1749 if (nsim_dev_port->port_index == port_index) 1750 return nsim_dev_port; 1751 return NULL; 1752 } 1753 1754 int nsim_drv_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, 1755 unsigned int port_index, u8 perm_addr[ETH_ALEN]) 1756 { 1757 struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); 1758 int err; 1759 1760 devl_lock(priv_to_devlink(nsim_dev)); 1761 if (__nsim_dev_port_lookup(nsim_dev, type, port_index)) 1762 err = -EEXIST; 1763 else 1764 err = __nsim_dev_port_add(nsim_dev, type, port_index, perm_addr); 1765 devl_unlock(priv_to_devlink(nsim_dev)); 1766 return err; 1767 } 1768 1769 int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, 1770 unsigned int port_index) 1771 { 1772 struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); 1773 struct nsim_dev_port *nsim_dev_port; 1774 int err = 0; 1775 1776 devl_lock(priv_to_devlink(nsim_dev)); 1777 nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, port_index); 1778 if (!nsim_dev_port) 1779 err = -ENOENT; 1780 else 1781 __nsim_dev_port_del(nsim_dev_port); 1782 devl_unlock(priv_to_devlink(nsim_dev)); 1783 return err; 1784 } 1785 1786 int nsim_drv_configure_vfs(struct nsim_bus_dev *nsim_bus_dev, 1787 unsigned int num_vfs) 1788 { 1789 struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); 1790 struct devlink *devlink = priv_to_devlink(nsim_dev); 1791 int ret = 0; 1792 1793 devl_lock(devlink); 1794 if (nsim_bus_dev->num_vfs == num_vfs) 1795 goto exit_unlock; 1796 if (nsim_bus_dev->num_vfs && num_vfs) { 1797 ret = -EBUSY; 1798 goto exit_unlock; 1799 } 1800 if (num_vfs > NSIM_BUS_DEV_MAX_VFS) { 1801 ret = -ENOMEM; 1802 goto exit_unlock; 1803 } 1804 1805 nsim_bus_dev_set_vfs(nsim_bus_dev, num_vfs); 1806 if (nsim_esw_mode_is_switchdev(nsim_dev)) { 1807 if (num_vfs) { 1808 ret = nsim_esw_switchdev_enable(nsim_dev, NULL); 1809 if (ret) { 1810 nsim_bus_dev_set_vfs(nsim_bus_dev, 0); 1811 goto exit_unlock; 1812 } 1813 } else { 1814 nsim_esw_legacy_enable(nsim_dev, NULL); 1815 } 1816 } 1817 1818 exit_unlock: 1819 devl_unlock(devlink); 1820 1821 return ret; 1822 } 1823 1824 int nsim_dev_init(void) 1825 { 1826 nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL); 1827 return PTR_ERR_OR_ZERO(nsim_dev_ddir); 1828 } 1829 1830 void nsim_dev_exit(void) 1831 { 1832 debugfs_remove_recursive(nsim_dev_ddir); 1833 } 1834