aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-11-05 14:51:17 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-11-05 15:53:04 -0500
commitd5ae67bacd9654b0e26b9f248249e9ee1b6e338b (patch)
tree7462206b0153d069ab4421a0d9d299c419d3b56e /net/mac802154
parent12cb56c2370b2911295026630a71af044c12d2aa (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.c8
-rw-r--r--net/mac802154/ieee802154_i.h4
-rw-r--r--net/mac802154/iface.c158
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
30static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, 36static 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 {
73struct ieee802154_sub_if_data { 74struct 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
384void mac802154_wpan_setup(struct net_device *dev) 384static 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; 396static int
400 dev->netdev_ops = &mac802154_wpan_ops; 397ieee802154_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;
427void 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
447static int
448mac802154_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 *
475ieee802154_if_add(struct ieee802154_local *local, const char *name, 442ieee802154_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
506err_free:
507 free_netdev(dev);
508err: 503err:
509 return ERR_PTR(err); 504 free_netdev(ndev);
505 return ERR_PTR(ret);
510} 506}
511 507
512void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) 508void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)