diff options
Diffstat (limited to 'net/caif/caif_dev.c')
| -rw-r--r-- | net/caif/caif_dev.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 6d1d86be187b..0e651cf577cf 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <net/net_namespace.h> | 21 | #include <net/net_namespace.h> |
| 22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
| 23 | #include <net/caif/caif_device.h> | 23 | #include <net/caif/caif_device.h> |
| 24 | #include <net/caif/caif_dev.h> | ||
| 25 | #include <net/caif/caif_layer.h> | 24 | #include <net/caif/caif_layer.h> |
| 26 | #include <net/caif/cfpkt.h> | 25 | #include <net/caif/cfpkt.h> |
| 27 | #include <net/caif/cfcnfg.h> | 26 | #include <net/caif/cfcnfg.h> |
| @@ -43,11 +42,21 @@ struct caif_device_entry_list { | |||
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | struct caif_net { | 44 | struct caif_net { |
| 45 | struct cfcnfg *cfg; | ||
| 46 | struct caif_device_entry_list caifdevs; | 46 | struct caif_device_entry_list caifdevs; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | static int caif_net_id; | 49 | static int caif_net_id; |
| 50 | static struct cfcnfg *cfg; | 50 | |
| 51 | struct cfcnfg *get_cfcnfg(struct net *net) | ||
| 52 | { | ||
| 53 | struct caif_net *caifn; | ||
| 54 | BUG_ON(!net); | ||
| 55 | caifn = net_generic(net, caif_net_id); | ||
| 56 | BUG_ON(!caifn); | ||
| 57 | return caifn->cfg; | ||
| 58 | } | ||
| 59 | EXPORT_SYMBOL(get_cfcnfg); | ||
| 51 | 60 | ||
| 52 | static struct caif_device_entry_list *caif_device_list(struct net *net) | 61 | static struct caif_device_entry_list *caif_device_list(struct net *net) |
| 53 | { | 62 | { |
| @@ -191,12 +200,17 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 191 | struct caif_dev_common *caifdev; | 200 | struct caif_dev_common *caifdev; |
| 192 | enum cfcnfg_phy_preference pref; | 201 | enum cfcnfg_phy_preference pref; |
| 193 | enum cfcnfg_phy_type phy_type; | 202 | enum cfcnfg_phy_type phy_type; |
| 203 | struct cfcnfg *cfg; | ||
| 194 | struct caif_device_entry_list *caifdevs = | 204 | struct caif_device_entry_list *caifdevs = |
| 195 | caif_device_list(dev_net(dev)); | 205 | caif_device_list(dev_net(dev)); |
| 196 | 206 | ||
| 197 | if (dev->type != ARPHRD_CAIF) | 207 | if (dev->type != ARPHRD_CAIF) |
| 198 | return 0; | 208 | return 0; |
| 199 | 209 | ||
| 210 | cfg = get_cfcnfg(dev_net(dev)); | ||
| 211 | if (cfg == NULL) | ||
| 212 | return 0; | ||
| 213 | |||
| 200 | switch (what) { | 214 | switch (what) { |
| 201 | case NETDEV_REGISTER: | 215 | case NETDEV_REGISTER: |
| 202 | caifd = caif_device_alloc(dev); | 216 | caifd = caif_device_alloc(dev); |
| @@ -235,7 +249,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 235 | phy_type, | 249 | phy_type, |
| 236 | dev, | 250 | dev, |
| 237 | &caifd->layer, | 251 | &caifd->layer, |
| 238 | 0, | ||
| 239 | pref, | 252 | pref, |
| 240 | caifdev->use_fcs, | 253 | caifdev->use_fcs, |
| 241 | caifdev->use_stx); | 254 | caifdev->use_stx); |
| @@ -323,35 +336,20 @@ static struct notifier_block caif_device_notifier = { | |||
| 323 | .priority = 0, | 336 | .priority = 0, |
| 324 | }; | 337 | }; |
| 325 | 338 | ||
| 326 | int caif_connect_client(struct caif_connect_request *conn_req, | ||
| 327 | struct cflayer *client_layer, int *ifindex, | ||
| 328 | int *headroom, int *tailroom) | ||
| 329 | { | ||
| 330 | struct cfctrl_link_param param; | ||
| 331 | int ret; | ||
| 332 | |||
| 333 | ret = caif_connect_req_to_link_param(cfg, conn_req, ¶m); | ||
| 334 | if (ret) | ||
| 335 | return ret; | ||
| 336 | /* Hook up the adaptation layer. */ | ||
| 337 | return cfcnfg_add_adaptation_layer(cfg, ¶m, | ||
| 338 | client_layer, ifindex, | ||
| 339 | headroom, tailroom); | ||
| 340 | } | ||
| 341 | EXPORT_SYMBOL(caif_connect_client); | ||
| 342 | |||
| 343 | int caif_disconnect_client(struct cflayer *adap_layer) | ||
| 344 | { | ||
| 345 | return cfcnfg_disconn_adapt_layer(cfg, adap_layer); | ||
| 346 | } | ||
| 347 | EXPORT_SYMBOL(caif_disconnect_client); | ||
| 348 | |||
| 349 | /* Per-namespace Caif devices handling */ | 339 | /* Per-namespace Caif devices handling */ |
| 350 | static int caif_init_net(struct net *net) | 340 | static int caif_init_net(struct net *net) |
| 351 | { | 341 | { |
| 352 | struct caif_net *caifn = net_generic(net, caif_net_id); | 342 | struct caif_net *caifn = net_generic(net, caif_net_id); |
| 343 | BUG_ON(!caifn); | ||
| 353 | INIT_LIST_HEAD(&caifn->caifdevs.list); | 344 | INIT_LIST_HEAD(&caifn->caifdevs.list); |
| 354 | mutex_init(&caifn->caifdevs.lock); | 345 | mutex_init(&caifn->caifdevs.lock); |
| 346 | |||
| 347 | caifn->cfg = cfcnfg_create(); | ||
| 348 | if (!caifn->cfg) { | ||
| 349 | pr_warn("can't create cfcnfg\n"); | ||
| 350 | return -ENOMEM; | ||
| 351 | } | ||
| 352 | |||
| 355 | return 0; | 353 | return 0; |
| 356 | } | 354 | } |
| 357 | 355 | ||
| @@ -360,10 +358,17 @@ static void caif_exit_net(struct net *net) | |||
| 360 | struct caif_device_entry *caifd, *tmp; | 358 | struct caif_device_entry *caifd, *tmp; |
| 361 | struct caif_device_entry_list *caifdevs = | 359 | struct caif_device_entry_list *caifdevs = |
| 362 | caif_device_list(net); | 360 | caif_device_list(net); |
| 361 | struct cfcnfg *cfg; | ||
| 363 | 362 | ||
| 364 | rtnl_lock(); | 363 | rtnl_lock(); |
| 365 | mutex_lock(&caifdevs->lock); | 364 | mutex_lock(&caifdevs->lock); |
| 366 | 365 | ||
| 366 | cfg = get_cfcnfg(net); | ||
| 367 | if (cfg == NULL) { | ||
| 368 | mutex_unlock(&caifdevs->lock); | ||
| 369 | return; | ||
| 370 | } | ||
| 371 | |||
| 367 | list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) { | 372 | list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) { |
| 368 | int i = 0; | 373 | int i = 0; |
| 369 | list_del_rcu(&caifd->list); | 374 | list_del_rcu(&caifd->list); |
| @@ -382,7 +387,7 @@ static void caif_exit_net(struct net *net) | |||
| 382 | free_percpu(caifd->pcpu_refcnt); | 387 | free_percpu(caifd->pcpu_refcnt); |
| 383 | kfree(caifd); | 388 | kfree(caifd); |
| 384 | } | 389 | } |
| 385 | 390 | cfcnfg_remove(cfg); | |
| 386 | 391 | ||
| 387 | mutex_unlock(&caifdevs->lock); | 392 | mutex_unlock(&caifdevs->lock); |
| 388 | rtnl_unlock(); | 393 | rtnl_unlock(); |
| @@ -400,32 +405,22 @@ static int __init caif_device_init(void) | |||
| 400 | { | 405 | { |
| 401 | int result; | 406 | int result; |
| 402 | 407 | ||
| 403 | cfg = cfcnfg_create(); | ||
| 404 | if (!cfg) { | ||
| 405 | pr_warn("can't create cfcnfg\n"); | ||
| 406 | goto err_cfcnfg_create_failed; | ||
| 407 | } | ||
| 408 | result = register_pernet_device(&caif_net_ops); | 408 | result = register_pernet_device(&caif_net_ops); |
| 409 | 409 | ||
| 410 | if (result) { | 410 | if (result) |
| 411 | kfree(cfg); | ||
| 412 | cfg = NULL; | ||
| 413 | return result; | 411 | return result; |
| 414 | } | 412 | |
| 415 | dev_add_pack(&caif_packet_type); | ||
| 416 | register_netdevice_notifier(&caif_device_notifier); | 413 | register_netdevice_notifier(&caif_device_notifier); |
| 414 | dev_add_pack(&caif_packet_type); | ||
| 417 | 415 | ||
| 418 | return result; | 416 | return result; |
| 419 | err_cfcnfg_create_failed: | ||
| 420 | return -ENODEV; | ||
| 421 | } | 417 | } |
| 422 | 418 | ||
| 423 | static void __exit caif_device_exit(void) | 419 | static void __exit caif_device_exit(void) |
| 424 | { | 420 | { |
| 425 | dev_remove_pack(&caif_packet_type); | ||
| 426 | unregister_pernet_device(&caif_net_ops); | 421 | unregister_pernet_device(&caif_net_ops); |
| 427 | unregister_netdevice_notifier(&caif_device_notifier); | 422 | unregister_netdevice_notifier(&caif_device_notifier); |
| 428 | cfcnfg_remove(cfg); | 423 | dev_remove_pack(&caif_packet_type); |
| 429 | } | 424 | } |
| 430 | 425 | ||
| 431 | module_init(caif_device_init); | 426 | module_init(caif_device_init); |
