goto err_fib_destroy; err = nsim_dev_traps_init(devlink); if (err) goto err_dummy_region_exit; err = nsim_dev_health_init(nsim_dev, devlink); if (err) goto err_traps_exit; err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); if (err) goto err_health_exit; nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, nsim_dev, &nsim_dev_take_snapshot_fops); return 0; err_health_exit: nsim_dev_health_exit(nsim_dev);err_traps_exit: nsim_dev_traps_exit(devlink);err_dummy_region_exit: nsim_dev_dummy_region_exit(nsim_dev);err_fib_destroy: nsim_fib_destroy(devlink, nsim_dev->fib_data); return err;} int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev){ struct nsim_dev *nsim_dev; struct devlink *devlink; int err; devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev)); if (!devlink) return -ENOMEM; devlink_net_set(devlink, nsim_bus_dev->initial_net); nsim_dev = devlink_priv(devlink); nsim_dev->nsim_bus_dev = nsim_bus_dev; nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id); get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); INIT_LIST_HEAD(&nsim_dev->port_list); mutex_init(&nsim_dev->port_list_lock); nsim_dev->fw_update_status = true; nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; spin_lock_init(&nsim_dev->fa_cookie_lock); dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); err = nsim_dev_resources_register(devlink); if (err) goto err_devlink_free; nsim_dev->fib_data = nsim_fib_create(devlink, NULL); if (IS_ERR(nsim_dev->fib_data)) { err = PTR_ERR(nsim_dev->fib_data); goto err_resources_unregister; } err = devlink_register(devlink, &nsim_bus_dev->dev); if (err) goto err_fib_destroy; err = devlink_params_register(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); if (err) goto err_dl_unregister; nsim_devlink_set_params_init_values(nsim_dev, devlink); err = nsim_dev_dummy_region_init(nsim_dev, devlink); if (err) goto err_params_unregister; err = nsim_dev_traps_init(devlink); if (err) goto err_dummy_region_exit; err = nsim_dev_debugfs_init(nsim_dev); if (err) goto err_traps_exit; err = nsim_dev_health_init(nsim_dev, devlink); if (err) goto err_debugfs_exit; err = nsim_bpf_dev_init(nsim_dev); if (err) goto err_health_exit; err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); if (err) goto err_bpf_dev_exit; devlink_params_publish(devlink); devlink_reload_enable(devlink); return 0; err_bpf_dev_exit: nsim_bpf_dev_exit(nsim_dev);err_health_exit: nsim_dev_health_exit(nsim_dev);err_debugfs_exit: nsim_dev_debugfs_exit(nsim_dev);err_traps_exit: nsim_dev_traps_exit(devlink);err_dummy_region_exit: nsim_dev_dummy_region_exit(nsim_dev);err_params_unregister: devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params));err_dl_unregister: devlink_unregister(devlink);err_fib_destroy: nsim_fib_destroy(devlink, nsim_dev->fib_data);err_resources_unregister: devlink_resources_unregister(devlink, NULL);err_devlink_free: devlink_free(devlink); return err;} static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev){ struct devlink *devlink = priv_to_devlink(nsim_dev); if (devlink_is_reload_failed(devlink)) return; debugfs_remove(nsim_dev->take_snapshot); nsim_dev_port_del_all(nsim_dev); nsim_dev_health_exit(nsim_dev); nsim_dev_traps_exit(devlink); nsim_dev_dummy_region_exit(nsim_dev); mutex_destroy(&nsim_dev->port_list_lock); nsim_fib_destroy(devlink, nsim_dev->fib_data);} void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev){ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); struct devlink *devlink = priv_to_devlink(nsim_dev); devlink_reload_disable(devlink); nsim_dev_reload_destroy(nsim_dev); nsim_bpf_dev_exit(nsim_dev); nsim_dev_debugfs_exit(nsim_dev); devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); devlink_unregister(devlink); devlink_resources_unregister(devlink, NULL); devlink_free(devlink);} static struct nsim_dev_port *__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index){ struct nsim_dev_port *nsim_dev_port; list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) if (nsim_dev_port->port_index == port_index) return nsim_dev_port; return NULL;} int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_index){ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); int err; mutex_lock(&nsim_dev->port_list_lock); if (__nsim_dev_port_lookup(nsim_dev, port_index)) err = -EEXIST; else err = __nsim_dev_port_add(nsim_dev, port_index); mutex_unlock(&nsim_dev->port_list_lock); return err;} int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_index){ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); struct nsim_dev_port *nsim_dev_port; int err = 0; mutex_lock(&nsim_dev->port_list_lock); nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index); if (!nsim_dev_port) err = -ENOENT; else __nsim_dev_port_del(nsim_dev_port); mutex_unlock(&nsim_dev->port_list_lock); return err;} int nsim_dev_init(void){ nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL); return PTR_ERR_OR_ZERO(nsim_dev_ddir);} void nsim_dev_exit(void){ debugfs_remove_recursive(nsim_dev_ddir);}Lines 1001–1213 of 1213. Previous lines
goto err_fib_destroy; err = nsim_dev_traps_init(devlink); if (err) goto err_dummy_region_exit; err = nsim_dev_health_init(nsim_dev, devlink); if (err) goto err_traps_exit; err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); if (err) goto err_health_exit; nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, nsim_dev, &nsim_dev_take_snapshot_fops); return 0; err_health_exit: nsim_dev_health_exit(nsim_dev); err_traps_exit: nsim_dev_traps_exit(devlink); err_dummy_region_exit: nsim_dev_dummy_region_exit(nsim_dev); err_fib_destroy: nsim_fib_destroy(devlink, nsim_dev->fib_data); return err; } int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) { struct nsim_dev *nsim_dev; struct devlink *devlink; int err; devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev)); if (!devlink) return -ENOMEM; devlink_net_set(devlink, nsim_bus_dev->initial_net); nsim_dev = devlink_priv(devlink); nsim_dev->nsim_bus_dev = nsim_bus_dev; nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id); get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); INIT_LIST_HEAD(&nsim_dev->port_list); mutex_init(&nsim_dev->port_list_lock); nsim_dev->fw_update_status = true; nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; spin_lock_init(&nsim_dev->fa_cookie_lock); dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); err = nsim_dev_resources_register(devlink); if (err) goto err_devlink_free; nsim_dev->fib_data = nsim_fib_create(devlink, NULL); if (IS_ERR(nsim_dev->fib_data)) { err = PTR_ERR(nsim_dev->fib_data); goto err_resources_unregister; } err = devlink_register(devlink, &nsim_bus_dev->dev); if (err) goto err_fib_destroy; err = devlink_params_register(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); if (err) goto err_dl_unregister; nsim_devlink_set_params_init_values(nsim_dev, devlink); err = nsim_dev_dummy_region_init(nsim_dev, devlink); if (err) goto err_params_unregister; err = nsim_dev_traps_init(devlink); if (err) goto err_dummy_region_exit; err = nsim_dev_debugfs_init(nsim_dev); if (err) goto err_traps_exit; err = nsim_dev_health_init(nsim_dev, devlink); if (err) goto err_debugfs_exit; err = nsim_bpf_dev_init(nsim_dev); if (err) goto err_health_exit; err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); if (err) goto err_bpf_dev_exit; devlink_params_publish(devlink); devlink_reload_enable(devlink); return 0; err_bpf_dev_exit: nsim_bpf_dev_exit(nsim_dev); err_health_exit: nsim_dev_health_exit(nsim_dev); err_debugfs_exit: nsim_dev_debugfs_exit(nsim_dev); err_traps_exit: nsim_dev_traps_exit(devlink); err_dummy_region_exit: nsim_dev_dummy_region_exit(nsim_dev); err_params_unregister: devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); err_dl_unregister: devlink_unregister(devlink); err_fib_destroy: nsim_fib_destroy(devlink, nsim_dev->fib_data); err_resources_unregister: devlink_resources_unregister(devlink, NULL); err_devlink_free: devlink_free(devlink); return err; } static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) { struct devlink *devlink = priv_to_devlink(nsim_dev); if (devlink_is_reload_failed(devlink)) return; debugfs_remove(nsim_dev->take_snapshot); nsim_dev_port_del_all(nsim_dev); nsim_dev_health_exit(nsim_dev); nsim_dev_traps_exit(devlink); nsim_dev_dummy_region_exit(nsim_dev); mutex_destroy(&nsim_dev->port_list_lock); nsim_fib_destroy(devlink, nsim_dev->fib_data); } void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev) { struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); struct devlink *devlink = priv_to_devlink(nsim_dev); devlink_reload_disable(devlink); nsim_dev_reload_destroy(nsim_dev); nsim_bpf_dev_exit(nsim_dev); nsim_dev_debugfs_exit(nsim_dev); devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); devlink_unregister(devlink); devlink_resources_unregister(devlink, NULL); devlink_free(devlink); } static struct nsim_dev_port * __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index) { struct nsim_dev_port *nsim_dev_port; list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) if (nsim_dev_port->port_index == port_index) return nsim_dev_port; return NULL; } int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_index) { struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); int err; mutex_lock(&nsim_dev->port_list_lock); if (__nsim_dev_port_lookup(nsim_dev, port_index)) err = -EEXIST; else err = __nsim_dev_port_add(nsim_dev, port_index); mutex_unlock(&nsim_dev->port_list_lock); return err; } int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_index) { struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); struct nsim_dev_port *nsim_dev_port; int err = 0; mutex_lock(&nsim_dev->port_list_lock); nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index); if (!nsim_dev_port) err = -ENOENT; else __nsim_dev_port_del(nsim_dev_port); mutex_unlock(&nsim_dev->port_list_lock); return err; } int nsim_dev_init(void) { nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL); return PTR_ERR_OR_ZERO(nsim_dev_ddir); } void nsim_dev_exit(void) { debugfs_remove_recursive(nsim_dev_ddir); }