diff options
| -rw-r--r-- | include/linux/ieee802154.h | 2 | ||||
| -rw-r--r-- | include/net/cfg802154.h | 2 | ||||
| -rw-r--r-- | net/ieee802154/nl802154.c | 31 | ||||
| -rw-r--r-- | net/ieee802154/rdev-ops.h | 7 | ||||
| -rw-r--r-- | net/mac802154/cfg.c | 26 |
5 files changed, 68 insertions, 0 deletions
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index d40379876b84..ce0f96a55976 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | #define IEEE802154_MIN_PSDU_LEN 5 | 31 | #define IEEE802154_MIN_PSDU_LEN 5 |
| 32 | 32 | ||
| 33 | #define IEEE802154_PAN_ID_BROADCAST 0xffff | 33 | #define IEEE802154_PAN_ID_BROADCAST 0xffff |
| 34 | #define IEEE802154_ADDR_SHORT_BROADCAST 0xffff | ||
| 35 | #define IEEE802154_ADDR_SHORT_UNSPEC 0xfffe | ||
| 34 | 36 | ||
| 35 | #define IEEE802154_EXTENDED_ADDR_LEN 8 | 37 | #define IEEE802154_EXTENDED_ADDR_LEN 8 |
| 36 | 38 | ||
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index d07b0726b285..e8a4c2b70720 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h | |||
| @@ -40,6 +40,8 @@ struct cfg802154_ops { | |||
| 40 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); | 40 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); |
| 41 | int (*set_pan_id)(struct wpan_phy *wpan_phy, | 41 | int (*set_pan_id)(struct wpan_phy *wpan_phy, |
| 42 | struct wpan_dev *wpan_dev, u16 pan_id); | 42 | struct wpan_dev *wpan_dev, u16 pan_id); |
| 43 | int (*set_short_addr)(struct wpan_phy *wpan_phy, | ||
| 44 | struct wpan_dev *wpan_dev, u16 short_addr); | ||
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| 45 | struct wpan_phy { | 47 | struct wpan_phy { |
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 88cd1293283a..2978c1a78017 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
| @@ -593,6 +593,29 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) | |||
| 593 | return rdev_set_pan_id(rdev, wpan_dev, pan_id); | 593 | return rdev_set_pan_id(rdev, wpan_dev, pan_id); |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) | ||
| 597 | { | ||
| 598 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | ||
| 599 | struct net_device *dev = info->user_ptr[1]; | ||
| 600 | struct wpan_dev *wpan_dev = dev->ieee802154_ptr; | ||
| 601 | u16 short_addr; | ||
| 602 | |||
| 603 | /* conflict here while tx/rx calls */ | ||
| 604 | if (netif_running(dev)) | ||
| 605 | return -EBUSY; | ||
| 606 | |||
| 607 | /* don't change address fields on monitor */ | ||
| 608 | if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) | ||
| 609 | return -EINVAL; | ||
| 610 | |||
| 611 | if (!info->attrs[NL802154_ATTR_SHORT_ADDR]) | ||
| 612 | return -EINVAL; | ||
| 613 | |||
| 614 | short_addr = nla_get_u16(info->attrs[NL802154_ATTR_SHORT_ADDR]); | ||
| 615 | |||
| 616 | return rdev_set_short_addr(rdev, wpan_dev, short_addr); | ||
| 617 | } | ||
| 618 | |||
| 596 | #define NL802154_FLAG_NEED_WPAN_PHY 0x01 | 619 | #define NL802154_FLAG_NEED_WPAN_PHY 0x01 |
| 597 | #define NL802154_FLAG_NEED_NETDEV 0x02 | 620 | #define NL802154_FLAG_NEED_NETDEV 0x02 |
| 598 | #define NL802154_FLAG_NEED_RTNL 0x04 | 621 | #define NL802154_FLAG_NEED_RTNL 0x04 |
| @@ -719,6 +742,14 @@ static const struct genl_ops nl802154_ops[] = { | |||
| 719 | .internal_flags = NL802154_FLAG_NEED_NETDEV | | 742 | .internal_flags = NL802154_FLAG_NEED_NETDEV | |
| 720 | NL802154_FLAG_NEED_RTNL, | 743 | NL802154_FLAG_NEED_RTNL, |
| 721 | }, | 744 | }, |
| 745 | { | ||
| 746 | .cmd = NL802154_CMD_SET_SHORT_ADDR, | ||
| 747 | .doit = nl802154_set_short_addr, | ||
| 748 | .policy = nl802154_policy, | ||
| 749 | .flags = GENL_ADMIN_PERM, | ||
| 750 | .internal_flags = NL802154_FLAG_NEED_NETDEV | | ||
| 751 | NL802154_FLAG_NEED_RTNL, | ||
| 752 | }, | ||
| 722 | }; | 753 | }; |
| 723 | 754 | ||
| 724 | /* initialisation/exit functions */ | 755 | /* initialisation/exit functions */ |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 4115ea264fd5..16b0de06c3af 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
| @@ -34,4 +34,11 @@ rdev_set_pan_id(struct cfg802154_registered_device *rdev, | |||
| 34 | return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); | 34 | return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static inline int | ||
| 38 | rdev_set_short_addr(struct cfg802154_registered_device *rdev, | ||
| 39 | struct wpan_dev *wpan_dev, u16 short_addr) | ||
| 40 | { | ||
| 41 | return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); | ||
| 42 | } | ||
| 43 | |||
| 37 | #endif /* __CFG802154_RDEV_OPS */ | 44 | #endif /* __CFG802154_RDEV_OPS */ |
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index db6e5e981a83..df29976d1321 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
| @@ -83,9 +83,35 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, | |||
| 83 | return 0; | 83 | return 0; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static int | ||
| 87 | ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, | ||
| 88 | const u16 short_addr) | ||
| 89 | { | ||
| 90 | ASSERT_RTNL(); | ||
| 91 | |||
| 92 | /* TODO | ||
| 93 | * I am not sure about to check here on broadcast short_addr. | ||
| 94 | * Broadcast is a valid setting, comment from 802.15.4: | ||
| 95 | * A value of 0xfffe indicates that the device has | ||
| 96 | * associated but has not been allocated an address. A | ||
| 97 | * value of 0xffff indicates that the device does not | ||
| 98 | * have a short address. | ||
| 99 | * | ||
| 100 | * I think we should allow to set these settings but | ||
| 101 | * don't allow to allow socket communication with it. | ||
| 102 | */ | ||
| 103 | if (short_addr == IEEE802154_ADDR_SHORT_UNSPEC || | ||
| 104 | short_addr == IEEE802154_ADDR_SHORT_BROADCAST) | ||
| 105 | return -EINVAL; | ||
| 106 | |||
| 107 | wpan_dev->short_addr = cpu_to_le16(short_addr); | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 86 | const struct cfg802154_ops mac802154_config_ops = { | 111 | const struct cfg802154_ops mac802154_config_ops = { |
| 87 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, | 112 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, |
| 88 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, | 113 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, |
| 89 | .set_channel = ieee802154_set_channel, | 114 | .set_channel = ieee802154_set_channel, |
| 90 | .set_pan_id = ieee802154_set_pan_id, | 115 | .set_pan_id = ieee802154_set_pan_id, |
| 116 | .set_short_addr = ieee802154_set_short_addr, | ||
| 91 | }; | 117 | }; |
