diff options
| author | Alexander Aring <alex.aring@gmail.com> | 2014-11-17 02:20:52 -0500 |
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2014-11-17 03:49:16 -0500 |
| commit | 0e57547eb7f0aa99aba32b50c49dbd722a80d6fb (patch) | |
| tree | ca66721d651bfa5ca441546976a83dc2b88af86b | |
| parent | f3ea5e44231a88eaea69a13410d1b80c19cfa1df (diff) | |
ieee802154: setting extended address while iface add
This patch adds support for setting an extended address while
registration a new interface. If ieee802154_is_valid_extended_addr
getting as parameter and invalid extended address then the perm address
is fallback. This is useful to make some default handling while for
example default registration of a wpan interface while phy registration.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
| -rw-r--r-- | include/net/cfg802154.h | 3 | ||||
| -rw-r--r-- | net/ieee802154/nl802154.c | 8 | ||||
| -rw-r--r-- | net/ieee802154/rdev-ops.h | 5 | ||||
| -rw-r--r-- | net/mac802154/cfg.c | 7 | ||||
| -rw-r--r-- | net/mac802154/ieee802154_i.h | 2 | ||||
| -rw-r--r-- | net/mac802154/iface.c | 12 | ||||
| -rw-r--r-- | net/mac802154/main.c | 3 |
7 files changed, 27 insertions, 13 deletions
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 24c7321f3647..4a9bb0e3db2b 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h | |||
| @@ -41,7 +41,8 @@ struct cfg802154_ops { | |||
| 41 | struct net_device *dev); | 41 | struct net_device *dev); |
| 42 | int (*add_virtual_intf)(struct wpan_phy *wpan_phy, | 42 | int (*add_virtual_intf)(struct wpan_phy *wpan_phy, |
| 43 | const char *name, | 43 | const char *name, |
| 44 | enum nl802154_iftype type); | 44 | enum nl802154_iftype type, |
| 45 | __le64 extended_addr); | ||
| 45 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); | 46 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); |
| 46 | int (*set_pan_id)(struct wpan_phy *wpan_phy, | 47 | int (*set_pan_id)(struct wpan_phy *wpan_phy, |
| 47 | struct wpan_dev *wpan_dev, u16 pan_id); | 48 | struct wpan_dev *wpan_dev, u16 pan_id); |
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index e7224f3c1584..49c4d8a5004a 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
| @@ -555,6 +555,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
| 555 | { | 555 | { |
| 556 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | 556 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; |
| 557 | enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; | 557 | enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; |
| 558 | __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL); | ||
| 558 | 559 | ||
| 559 | /* TODO avoid failing a new interface | 560 | /* TODO avoid failing a new interface |
| 560 | * creation due to pending removal? | 561 | * creation due to pending removal? |
| @@ -569,12 +570,17 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
| 569 | return -EINVAL; | 570 | return -EINVAL; |
| 570 | } | 571 | } |
| 571 | 572 | ||
| 573 | /* TODO add nla_get_le64 to netlink */ | ||
| 574 | if (info->attrs[NL802154_ATTR_EXTENDED_ADDR]) | ||
| 575 | extended_addr = (__force __le64)nla_get_u64( | ||
| 576 | info->attrs[NL802154_ATTR_EXTENDED_ADDR]); | ||
| 577 | |||
| 572 | if (!rdev->ops->add_virtual_intf) | 578 | if (!rdev->ops->add_virtual_intf) |
| 573 | return -EOPNOTSUPP; | 579 | return -EOPNOTSUPP; |
| 574 | 580 | ||
| 575 | return rdev_add_virtual_intf(rdev, | 581 | return rdev_add_virtual_intf(rdev, |
| 576 | nla_data(info->attrs[NL802154_ATTR_IFNAME]), | 582 | nla_data(info->attrs[NL802154_ATTR_IFNAME]), |
| 577 | type); | 583 | type, extended_addr); |
| 578 | } | 584 | } |
| 579 | 585 | ||
| 580 | static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) | 586 | static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index d3a4f94c5fdc..06e97542dafb 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
| @@ -22,9 +22,10 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, | |||
| 22 | 22 | ||
| 23 | static inline int | 23 | static inline int |
| 24 | rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, | 24 | rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, |
| 25 | enum nl802154_iftype type) | 25 | enum nl802154_iftype type, __le64 extended_addr) |
| 26 | { | 26 | { |
| 27 | return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type); | 27 | return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type, |
| 28 | extended_addr); | ||
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | static inline int | 31 | static inline int |
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index ae1a9ef2d42c..568d712bfc8c 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
| @@ -28,7 +28,8 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, | |||
| 28 | struct net_device *dev; | 28 | struct net_device *dev; |
| 29 | 29 | ||
| 30 | rtnl_lock(); | 30 | rtnl_lock(); |
| 31 | dev = ieee802154_if_add(local, name, type); | 31 | dev = ieee802154_if_add(local, name, type, |
| 32 | cpu_to_le64(0x0000000000000000ULL)); | ||
| 32 | rtnl_unlock(); | 33 | rtnl_unlock(); |
| 33 | 34 | ||
| 34 | return dev; | 35 | return dev; |
| @@ -44,12 +45,12 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, | |||
| 44 | 45 | ||
| 45 | static int | 46 | static int |
| 46 | ieee802154_add_iface(struct wpan_phy *phy, const char *name, | 47 | ieee802154_add_iface(struct wpan_phy *phy, const char *name, |
| 47 | enum nl802154_iftype type) | 48 | enum nl802154_iftype type, __le64 extended_addr) |
| 48 | { | 49 | { |
| 49 | struct ieee802154_local *local = wpan_phy_priv(phy); | 50 | struct ieee802154_local *local = wpan_phy_priv(phy); |
| 50 | struct net_device *err; | 51 | struct net_device *err; |
| 51 | 52 | ||
| 52 | err = ieee802154_if_add(local, name, type); | 53 | err = ieee802154_if_add(local, name, type, extended_addr); |
| 53 | if (IS_ERR(err)) | 54 | if (IS_ERR(err)) |
| 54 | return PTR_ERR(err); | 55 | return PTR_ERR(err); |
| 55 | 56 | ||
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 46553830896d..cc691637d24b 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h | |||
| @@ -176,7 +176,7 @@ void ieee802154_iface_exit(void); | |||
| 176 | void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); | 176 | void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); |
| 177 | struct net_device * | 177 | struct net_device * |
| 178 | ieee802154_if_add(struct ieee802154_local *local, const char *name, | 178 | ieee802154_if_add(struct ieee802154_local *local, const char *name, |
| 179 | enum nl802154_iftype type); | 179 | enum nl802154_iftype type, __le64 extended_addr); |
| 180 | void ieee802154_remove_interfaces(struct ieee802154_local *local); | 180 | void ieee802154_remove_interfaces(struct ieee802154_local *local); |
| 181 | 181 | ||
| 182 | #endif /* __IEEE802154_I_H */ | 182 | #endif /* __IEEE802154_I_H */ |
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index ba63ac93ae90..38dfc72d24b6 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c | |||
| @@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, | |||
| 458 | 458 | ||
| 459 | struct net_device * | 459 | struct net_device * |
| 460 | ieee802154_if_add(struct ieee802154_local *local, const char *name, | 460 | ieee802154_if_add(struct ieee802154_local *local, const char *name, |
| 461 | enum nl802154_iftype type) | 461 | enum nl802154_iftype type, __le64 extended_addr) |
| 462 | { | 462 | { |
| 463 | struct net_device *ndev = NULL; | 463 | struct net_device *ndev = NULL; |
| 464 | struct ieee802154_sub_if_data *sdata = NULL; | 464 | struct ieee802154_sub_if_data *sdata = NULL; |
| @@ -477,9 +477,16 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, | |||
| 477 | if (ret < 0) | 477 | if (ret < 0) |
| 478 | goto err; | 478 | goto err; |
| 479 | 479 | ||
| 480 | ieee802154_le64_to_be64(ndev->perm_addr, | ||
| 481 | &local->hw.phy->perm_extended_addr); | ||
| 480 | switch (type) { | 482 | switch (type) { |
| 481 | case NL802154_IFTYPE_NODE: | 483 | case NL802154_IFTYPE_NODE: |
| 482 | ndev->type = ARPHRD_IEEE802154; | 484 | ndev->type = ARPHRD_IEEE802154; |
| 485 | if (ieee802154_is_valid_extended_addr(extended_addr)) | ||
| 486 | ieee802154_le64_to_be64(ndev->dev_addr, &extended_addr); | ||
| 487 | else | ||
| 488 | memcpy(ndev->dev_addr, ndev->perm_addr, | ||
| 489 | IEEE802154_EXTENDED_ADDR_LEN); | ||
| 483 | break; | 490 | break; |
| 484 | case NL802154_IFTYPE_MONITOR: | 491 | case NL802154_IFTYPE_MONITOR: |
| 485 | ndev->type = ARPHRD_IEEE802154_MONITOR; | 492 | ndev->type = ARPHRD_IEEE802154_MONITOR; |
| @@ -489,9 +496,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, | |||
| 489 | goto err; | 496 | goto err; |
| 490 | } | 497 | } |
| 491 | 498 | ||
| 492 | ieee802154_le64_to_be64(ndev->perm_addr, | ||
| 493 | &local->hw.phy->perm_extended_addr); | ||
| 494 | memcpy(ndev->dev_addr, ndev->perm_addr, IEEE802154_EXTENDED_ADDR_LEN); | ||
| 495 | /* TODO check this */ | 499 | /* TODO check this */ |
| 496 | SET_NETDEV_DEV(ndev, &local->phy->dev); | 500 | SET_NETDEV_DEV(ndev, &local->phy->dev); |
| 497 | sdata = netdev_priv(ndev); | 501 | sdata = netdev_priv(ndev); |
diff --git a/net/mac802154/main.c b/net/mac802154/main.c index bbb19dd585a0..8500378c8318 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c | |||
| @@ -161,7 +161,8 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) | |||
| 161 | 161 | ||
| 162 | rtnl_lock(); | 162 | rtnl_lock(); |
| 163 | 163 | ||
| 164 | dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE); | 164 | dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE, |
| 165 | cpu_to_le64(0x0000000000000000ULL)); | ||
| 165 | if (IS_ERR(dev)) { | 166 | if (IS_ERR(dev)) { |
| 166 | rtnl_unlock(); | 167 | rtnl_unlock(); |
| 167 | rc = PTR_ERR(dev); | 168 | rc = PTR_ERR(dev); |
