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>
This commit is contained in:
parent
f3ea5e4423
commit
0e57547eb7
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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);
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user