Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alexander Aring and committed by
Marcel Holtmann
0e57547e f3ea5e44

+27 -13
+2 -1
include/net/cfg802154.h
··· 41 41 struct net_device *dev); 42 42 int (*add_virtual_intf)(struct wpan_phy *wpan_phy, 43 43 const char *name, 44 - enum nl802154_iftype type); 44 + enum nl802154_iftype type, 45 + __le64 extended_addr); 45 46 int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); 46 47 int (*set_pan_id)(struct wpan_phy *wpan_phy, 47 48 struct wpan_dev *wpan_dev, u16 pan_id);
+7 -1
net/ieee802154/nl802154.c
··· 555 555 { 556 556 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 557 557 enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; 558 + __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL); 558 559 559 560 /* TODO avoid failing a new interface 560 561 * creation due to pending removal? ··· 570 569 return -EINVAL; 571 570 } 572 571 572 + /* TODO add nla_get_le64 to netlink */ 573 + if (info->attrs[NL802154_ATTR_EXTENDED_ADDR]) 574 + extended_addr = (__force __le64)nla_get_u64( 575 + info->attrs[NL802154_ATTR_EXTENDED_ADDR]); 576 + 573 577 if (!rdev->ops->add_virtual_intf) 574 578 return -EOPNOTSUPP; 575 579 576 580 return rdev_add_virtual_intf(rdev, 577 581 nla_data(info->attrs[NL802154_ATTR_IFNAME]), 578 - type); 582 + type, extended_addr); 579 583 } 580 584 581 585 static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
+3 -2
net/ieee802154/rdev-ops.h
··· 22 22 23 23 static inline int 24 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 31 static inline int
+4 -3
net/mac802154/cfg.c
··· 28 28 struct net_device *dev; 29 29 30 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 33 rtnl_unlock(); 33 34 34 35 return dev; ··· 45 44 46 45 static int 47 46 ieee802154_add_iface(struct wpan_phy *phy, const char *name, 48 - enum nl802154_iftype type) 47 + enum nl802154_iftype type, __le64 extended_addr) 49 48 { 50 49 struct ieee802154_local *local = wpan_phy_priv(phy); 51 50 struct net_device *err; 52 51 53 - err = ieee802154_if_add(local, name, type); 52 + err = ieee802154_if_add(local, name, type, extended_addr); 54 53 if (IS_ERR(err)) 55 54 return PTR_ERR(err); 56 55
+1 -1
net/mac802154/ieee802154_i.h
··· 176 176 void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); 177 177 struct net_device * 178 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 180 void ieee802154_remove_interfaces(struct ieee802154_local *local); 181 181 182 182 #endif /* __IEEE802154_I_H */
+8 -4
net/mac802154/iface.c
··· 458 458 459 459 struct net_device * 460 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 463 struct net_device *ndev = NULL; 464 464 struct ieee802154_sub_if_data *sdata = NULL; ··· 477 477 if (ret < 0) 478 478 goto err; 479 479 480 + ieee802154_le64_to_be64(ndev->perm_addr, 481 + &local->hw.phy->perm_extended_addr); 480 482 switch (type) { 481 483 case NL802154_IFTYPE_NODE: 482 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 490 break; 484 491 case NL802154_IFTYPE_MONITOR: 485 492 ndev->type = ARPHRD_IEEE802154_MONITOR; ··· 496 489 goto err; 497 490 } 498 491 499 - ieee802154_le64_to_be64(ndev->perm_addr, 500 - &local->hw.phy->perm_extended_addr); 501 - memcpy(ndev->dev_addr, ndev->perm_addr, IEEE802154_EXTENDED_ADDR_LEN); 502 492 /* TODO check this */ 503 493 SET_NETDEV_DEV(ndev, &local->phy->dev); 504 494 sdata = netdev_priv(ndev);
+2 -1
net/mac802154/main.c
··· 161 161 162 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 166 if (IS_ERR(dev)) { 166 167 rtnl_unlock(); 167 168 rc = PTR_ERR(dev);