Commit 0e57547e authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann

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: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent f3ea5e44
...@@ -41,7 +41,8 @@ struct cfg802154_ops { ...@@ -41,7 +41,8 @@ struct cfg802154_ops {
struct net_device *dev); struct net_device *dev);
int (*add_virtual_intf)(struct wpan_phy *wpan_phy, int (*add_virtual_intf)(struct wpan_phy *wpan_phy,
const char *name, const char *name,
enum nl802154_iftype type); enum nl802154_iftype type,
__le64 extended_addr);
int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
int (*set_pan_id)(struct wpan_phy *wpan_phy, int (*set_pan_id)(struct wpan_phy *wpan_phy,
struct wpan_dev *wpan_dev, u16 pan_id); struct wpan_dev *wpan_dev, u16 pan_id);
......
...@@ -555,6 +555,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) ...@@ -555,6 +555,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg802154_registered_device *rdev = info->user_ptr[0]; struct cfg802154_registered_device *rdev = info->user_ptr[0];
enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC;
__le64 extended_addr = cpu_to_le64(0x0000000000000000ULL);
/* TODO avoid failing a new interface /* TODO avoid failing a new interface
* creation due to pending removal? * creation due to pending removal?
...@@ -569,12 +570,17 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) ...@@ -569,12 +570,17 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
} }
/* TODO add nla_get_le64 to netlink */
if (info->attrs[NL802154_ATTR_EXTENDED_ADDR])
extended_addr = (__force __le64)nla_get_u64(
info->attrs[NL802154_ATTR_EXTENDED_ADDR]);
if (!rdev->ops->add_virtual_intf) if (!rdev->ops->add_virtual_intf)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return rdev_add_virtual_intf(rdev, return rdev_add_virtual_intf(rdev,
nla_data(info->attrs[NL802154_ATTR_IFNAME]), nla_data(info->attrs[NL802154_ATTR_IFNAME]),
type); type, extended_addr);
} }
static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
......
...@@ -22,9 +22,10 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, ...@@ -22,9 +22,10 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
static inline int static inline int
rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name,
enum nl802154_iftype type) enum nl802154_iftype type, __le64 extended_addr)
{ {
return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type); return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type,
extended_addr);
} }
static inline int static inline int
......
...@@ -28,7 +28,8 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, ...@@ -28,7 +28,8 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
struct net_device *dev; struct net_device *dev;
rtnl_lock(); rtnl_lock();
dev = ieee802154_if_add(local, name, type); dev = ieee802154_if_add(local, name, type,
cpu_to_le64(0x0000000000000000ULL));
rtnl_unlock(); rtnl_unlock();
return dev; return dev;
...@@ -44,12 +45,12 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, ...@@ -44,12 +45,12 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
static int static int
ieee802154_add_iface(struct wpan_phy *phy, const char *name, ieee802154_add_iface(struct wpan_phy *phy, const char *name,
enum nl802154_iftype type) enum nl802154_iftype type, __le64 extended_addr)
{ {
struct ieee802154_local *local = wpan_phy_priv(phy); struct ieee802154_local *local = wpan_phy_priv(phy);
struct net_device *err; struct net_device *err;
err = ieee802154_if_add(local, name, type); err = ieee802154_if_add(local, name, type, extended_addr);
if (IS_ERR(err)) if (IS_ERR(err))
return PTR_ERR(err); return PTR_ERR(err);
......
...@@ -176,7 +176,7 @@ void ieee802154_iface_exit(void); ...@@ -176,7 +176,7 @@ void ieee802154_iface_exit(void);
void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
struct net_device * struct net_device *
ieee802154_if_add(struct ieee802154_local *local, const char *name, ieee802154_if_add(struct ieee802154_local *local, const char *name,
enum nl802154_iftype type); enum nl802154_iftype type, __le64 extended_addr);
void ieee802154_remove_interfaces(struct ieee802154_local *local); void ieee802154_remove_interfaces(struct ieee802154_local *local);
#endif /* __IEEE802154_I_H */ #endif /* __IEEE802154_I_H */
...@@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, ...@@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
struct net_device * struct net_device *
ieee802154_if_add(struct ieee802154_local *local, const char *name, ieee802154_if_add(struct ieee802154_local *local, const char *name,
enum nl802154_iftype type) enum nl802154_iftype type, __le64 extended_addr)
{ {
struct net_device *ndev = NULL; struct net_device *ndev = NULL;
struct ieee802154_sub_if_data *sdata = NULL; struct ieee802154_sub_if_data *sdata = NULL;
...@@ -477,9 +477,16 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, ...@@ -477,9 +477,16 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
if (ret < 0) if (ret < 0)
goto err; goto err;
ieee802154_le64_to_be64(ndev->perm_addr,
&local->hw.phy->perm_extended_addr);
switch (type) { switch (type) {
case NL802154_IFTYPE_NODE: case NL802154_IFTYPE_NODE:
ndev->type = ARPHRD_IEEE802154; ndev->type = ARPHRD_IEEE802154;
if (ieee802154_is_valid_extended_addr(extended_addr))
ieee802154_le64_to_be64(ndev->dev_addr, &extended_addr);
else
memcpy(ndev->dev_addr, ndev->perm_addr,
IEEE802154_EXTENDED_ADDR_LEN);
break; break;
case NL802154_IFTYPE_MONITOR: case NL802154_IFTYPE_MONITOR:
ndev->type = ARPHRD_IEEE802154_MONITOR; ndev->type = ARPHRD_IEEE802154_MONITOR;
...@@ -489,9 +496,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, ...@@ -489,9 +496,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
goto err; goto err;
} }
ieee802154_le64_to_be64(ndev->perm_addr,
&local->hw.phy->perm_extended_addr);
memcpy(ndev->dev_addr, ndev->perm_addr, IEEE802154_EXTENDED_ADDR_LEN);
/* TODO check this */ /* TODO check this */
SET_NETDEV_DEV(ndev, &local->phy->dev); SET_NETDEV_DEV(ndev, &local->phy->dev);
sdata = netdev_priv(ndev); sdata = netdev_priv(ndev);
......
...@@ -161,7 +161,8 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) ...@@ -161,7 +161,8 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
rtnl_lock(); rtnl_lock();
dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE); dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE,
cpu_to_le64(0x0000000000000000ULL));
if (IS_ERR(dev)) { if (IS_ERR(dev)) {
rtnl_unlock(); rtnl_unlock();
rc = PTR_ERR(dev); rc = PTR_ERR(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment