diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-11-05 14:51:17 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-11-05 15:53:04 -0500 |
commit | d5ae67bacd9654b0e26b9f248249e9ee1b6e338b (patch) | |
tree | 7462206b0153d069ab4421a0d9d299c419d3b56e /net/mac802154 | |
parent | 12cb56c2370b2911295026630a71af044c12d2aa (diff) |
ieee802154: rework interface registration
This patch meld mac802154_netdev_register into ieee802154_if_add
function. Also we have now only one alloc_netdev call with one interface
setup routine "ieee802154_if_setup" instead two different one for each
interface type. This patch checks via runtime the interface type and do
different handling now. Additional we add the wpan_dev struct in
ieee802154_sub_if_data and set the new ieee802154_ptr while netdev
registration. This behaviour is very similar the mac80211 netdev
registration functionality.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154')
-rw-r--r-- | net/mac802154/cfg.c | 8 | ||||
-rw-r--r-- | net/mac802154/ieee802154_i.h | 4 | ||||
-rw-r--r-- | net/mac802154/iface.c | 158 |
3 files changed, 88 insertions, 82 deletions
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 0a08f66512b3..d2c4e8f89720 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * Based on: net/mac80211/cfg.c | 13 | * Based on: net/mac80211/cfg.c |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <net/rtnetlink.h> | ||
16 | #include <net/cfg802154.h> | 17 | #include <net/cfg802154.h> |
17 | 18 | ||
18 | #include "ieee802154_i.h" | 19 | #include "ieee802154_i.h" |
@@ -23,8 +24,13 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, | |||
23 | const char *name, int type) | 24 | const char *name, int type) |
24 | { | 25 | { |
25 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); | 26 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); |
27 | struct net_device *dev; | ||
26 | 28 | ||
27 | return ieee802154_if_add(local, name, NULL, type); | 29 | rtnl_lock(); |
30 | dev = ieee802154_if_add(local, name, NULL, type); | ||
31 | rtnl_unlock(); | ||
32 | |||
33 | return dev; | ||
28 | } | 34 | } |
29 | 35 | ||
30 | static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, | 36 | static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, |
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 3ad85404fc94..748dc5afe367 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define __IEEE802154_I_H | 20 | #define __IEEE802154_I_H |
21 | 21 | ||
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <net/cfg802154.h> | ||
23 | #include <net/mac802154.h> | 24 | #include <net/mac802154.h> |
24 | #include <net/ieee802154_netdev.h> | 25 | #include <net/ieee802154_netdev.h> |
25 | 26 | ||
@@ -73,11 +74,14 @@ enum ieee802154_sdata_state_bits { | |||
73 | struct ieee802154_sub_if_data { | 74 | struct ieee802154_sub_if_data { |
74 | struct list_head list; /* the ieee802154_priv->slaves list */ | 75 | struct list_head list; /* the ieee802154_priv->slaves list */ |
75 | 76 | ||
77 | struct wpan_dev wpan_dev; | ||
78 | |||
76 | struct ieee802154_local *local; | 79 | struct ieee802154_local *local; |
77 | struct net_device *dev; | 80 | struct net_device *dev; |
78 | 81 | ||
79 | int type; | 82 | int type; |
80 | unsigned long state; | 83 | unsigned long state; |
84 | char name[IFNAMSIZ]; | ||
81 | 85 | ||
82 | spinlock_t mib_lock; | 86 | spinlock_t mib_lock; |
83 | 87 | ||
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 78cb38124a2a..f9ed608aa260 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c | |||
@@ -381,30 +381,23 @@ static void mac802154_wpan_free(struct net_device *dev) | |||
381 | free_netdev(dev); | 381 | free_netdev(dev); |
382 | } | 382 | } |
383 | 383 | ||
384 | void mac802154_wpan_setup(struct net_device *dev) | 384 | static void ieee802154_if_setup(struct net_device *dev) |
385 | { | 385 | { |
386 | struct ieee802154_sub_if_data *sdata; | ||
387 | |||
388 | dev->addr_len = IEEE802154_ADDR_LEN; | 386 | dev->addr_len = IEEE802154_ADDR_LEN; |
389 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); | 387 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); |
390 | 388 | ||
391 | dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; | 389 | dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; |
392 | dev->header_ops = &mac802154_header_ops; | ||
393 | dev->needed_tailroom = 2 + 16; /* FCS + MIC */ | 390 | dev->needed_tailroom = 2 + 16; /* FCS + MIC */ |
394 | dev->mtu = IEEE802154_MTU; | 391 | dev->mtu = IEEE802154_MTU; |
395 | dev->tx_queue_len = 300; | 392 | dev->tx_queue_len = 300; |
396 | dev->type = ARPHRD_IEEE802154; | ||
397 | dev->flags = IFF_NOARP | IFF_BROADCAST; | 393 | dev->flags = IFF_NOARP | IFF_BROADCAST; |
394 | } | ||
398 | 395 | ||
399 | dev->destructor = mac802154_wpan_free; | 396 | static int |
400 | dev->netdev_ops = &mac802154_wpan_ops; | 397 | ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) |
401 | dev->ml_priv = &mac802154_mlme_wpan; | 398 | { |
402 | 399 | /* set some type-dependent values */ | |
403 | sdata = IEEE802154_DEV_TO_SUB_IF(dev); | 400 | sdata->type = type; |
404 | sdata->type = IEEE802154_DEV_WPAN; | ||
405 | |||
406 | spin_lock_init(&sdata->mib_lock); | ||
407 | mutex_init(&sdata->sec_mtx); | ||
408 | 401 | ||
409 | get_random_bytes(&sdata->bsn, 1); | 402 | get_random_bytes(&sdata->bsn, 1); |
410 | get_random_bytes(&sdata->dsn, 1); | 403 | get_random_bytes(&sdata->dsn, 1); |
@@ -419,54 +412,28 @@ void mac802154_wpan_setup(struct net_device *dev) | |||
419 | sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); | 412 | sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); |
420 | sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); | 413 | sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); |
421 | 414 | ||
422 | sdata->promisuous_mode = false; | 415 | switch (type) { |
423 | 416 | case IEEE802154_DEV_WPAN: | |
424 | mac802154_llsec_init(&sdata->sec); | 417 | sdata->dev->header_ops = &mac802154_header_ops; |
425 | } | 418 | sdata->dev->destructor = mac802154_wpan_free; |
426 | 419 | sdata->dev->netdev_ops = &mac802154_wpan_ops; | |
427 | void mac802154_monitor_setup(struct net_device *dev) | 420 | sdata->dev->ml_priv = &mac802154_mlme_wpan; |
428 | { | 421 | sdata->promisuous_mode = false; |
429 | struct ieee802154_sub_if_data *sdata; | ||
430 | |||
431 | dev->needed_tailroom = 2; /* room for FCS */ | ||
432 | dev->mtu = IEEE802154_MTU; | ||
433 | dev->tx_queue_len = 10; | ||
434 | dev->type = ARPHRD_IEEE802154_MONITOR; | ||
435 | dev->flags = IFF_NOARP | IFF_BROADCAST; | ||
436 | |||
437 | dev->destructor = free_netdev; | ||
438 | dev->netdev_ops = &mac802154_monitor_ops; | ||
439 | dev->ml_priv = &mac802154_mlme_reduced; | ||
440 | |||
441 | sdata = IEEE802154_DEV_TO_SUB_IF(dev); | ||
442 | sdata->type = IEEE802154_DEV_MONITOR; | ||
443 | |||
444 | sdata->promisuous_mode = true; | ||
445 | } | ||
446 | |||
447 | static int | ||
448 | mac802154_netdev_register(struct ieee802154_local *local, | ||
449 | struct net_device *dev) | ||
450 | { | ||
451 | struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); | ||
452 | int err; | ||
453 | |||
454 | sdata->dev = dev; | ||
455 | sdata->local = local; | ||
456 | |||
457 | dev->needed_headroom = local->hw.extra_tx_headroom; | ||
458 | |||
459 | SET_NETDEV_DEV(dev, &local->phy->dev); | ||
460 | 422 | ||
461 | err = register_netdev(dev); | 423 | spin_lock_init(&sdata->mib_lock); |
462 | if (err < 0) | 424 | mutex_init(&sdata->sec_mtx); |
463 | return err; | ||
464 | 425 | ||
465 | rtnl_lock(); | 426 | mac802154_llsec_init(&sdata->sec); |
466 | mutex_lock(&local->iflist_mtx); | 427 | break; |
467 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 428 | case IEEE802154_DEV_MONITOR: |
468 | mutex_unlock(&local->iflist_mtx); | 429 | sdata->dev->destructor = free_netdev; |
469 | rtnl_unlock(); | 430 | sdata->dev->netdev_ops = &mac802154_monitor_ops; |
431 | sdata->dev->ml_priv = &mac802154_mlme_reduced; | ||
432 | sdata->promisuous_mode = true; | ||
433 | break; | ||
434 | default: | ||
435 | BUG(); | ||
436 | } | ||
470 | 437 | ||
471 | return 0; | 438 | return 0; |
472 | } | 439 | } |
@@ -475,38 +442,67 @@ struct net_device * | |||
475 | ieee802154_if_add(struct ieee802154_local *local, const char *name, | 442 | ieee802154_if_add(struct ieee802154_local *local, const char *name, |
476 | struct wpan_dev **new_wpan_dev, int type) | 443 | struct wpan_dev **new_wpan_dev, int type) |
477 | { | 444 | { |
478 | struct net_device *dev; | 445 | struct net_device *ndev = NULL; |
479 | int err = -ENOMEM; | 446 | struct ieee802154_sub_if_data *sdata = NULL; |
447 | int ret = -ENOMEM; | ||
448 | |||
449 | ASSERT_RTNL(); | ||
450 | |||
451 | ndev = alloc_netdev(sizeof(*sdata), name, NET_NAME_UNKNOWN, | ||
452 | ieee802154_if_setup); | ||
453 | if (!ndev) | ||
454 | return ERR_PTR(-ENOMEM); | ||
455 | |||
456 | ndev->needed_headroom = local->hw.extra_tx_headroom; | ||
457 | |||
458 | ret = dev_alloc_name(ndev, ndev->name); | ||
459 | if (ret < 0) | ||
460 | goto err; | ||
480 | 461 | ||
481 | switch (type) { | 462 | switch (type) { |
482 | case IEEE802154_DEV_MONITOR: | ||
483 | dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), | ||
484 | name, NET_NAME_UNKNOWN, | ||
485 | mac802154_monitor_setup); | ||
486 | break; | ||
487 | case IEEE802154_DEV_WPAN: | 463 | case IEEE802154_DEV_WPAN: |
488 | dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), | 464 | ndev->type = ARPHRD_IEEE802154; |
489 | name, NET_NAME_UNKNOWN, | ||
490 | mac802154_wpan_setup); | ||
491 | break; | 465 | break; |
492 | default: | 466 | case IEEE802154_DEV_MONITOR: |
493 | dev = NULL; | 467 | ndev->type = ARPHRD_IEEE802154_MONITOR; |
494 | err = -EINVAL; | ||
495 | break; | 468 | break; |
469 | default: | ||
470 | ret = -EINVAL; | ||
471 | goto err; | ||
496 | } | 472 | } |
497 | if (!dev) | 473 | |
474 | /* TODO check this */ | ||
475 | SET_NETDEV_DEV(ndev, &local->phy->dev); | ||
476 | sdata = netdev_priv(ndev); | ||
477 | ndev->ieee802154_ptr = &sdata->wpan_dev; | ||
478 | memcpy(sdata->name, ndev->name, IFNAMSIZ); | ||
479 | sdata->dev = ndev; | ||
480 | sdata->wpan_dev.wpan_phy = local->hw.phy; | ||
481 | sdata->local = local; | ||
482 | |||
483 | /* setup type-dependent data */ | ||
484 | ret = ieee802154_setup_sdata(sdata, type); | ||
485 | if (ret) | ||
498 | goto err; | 486 | goto err; |
499 | 487 | ||
500 | err = mac802154_netdev_register(local, dev); | 488 | if (ndev) { |
501 | if (err) | 489 | ret = register_netdevice(ndev); |
502 | goto err_free; | 490 | if (ret < 0) |
491 | goto err; | ||
492 | } | ||
493 | |||
494 | mutex_lock(&local->iflist_mtx); | ||
495 | list_add_tail_rcu(&sdata->list, &local->interfaces); | ||
496 | mutex_unlock(&local->iflist_mtx); | ||
503 | 497 | ||
504 | return dev; | 498 | if (new_wpan_dev) |
499 | *new_wpan_dev = &sdata->wpan_dev; | ||
500 | |||
501 | return ndev; | ||
505 | 502 | ||
506 | err_free: | ||
507 | free_netdev(dev); | ||
508 | err: | 503 | err: |
509 | return ERR_PTR(err); | 504 | free_netdev(ndev); |
505 | return ERR_PTR(ret); | ||
510 | } | 506 | } |
511 | 507 | ||
512 | void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) | 508 | void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) |