diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ieee802154/nl802154.c | 34 | ||||
-rw-r--r-- | net/ieee802154/rdev-ops.h | 7 | ||||
-rw-r--r-- | net/mac802154/cfg.c | 15 |
3 files changed, 56 insertions, 0 deletions
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index ccdf33ecee0b..e7224f3c1584 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
@@ -551,6 +551,32 @@ static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
551 | return genlmsg_reply(msg, info); | 551 | return genlmsg_reply(msg, info); |
552 | } | 552 | } |
553 | 553 | ||
554 | static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) | ||
555 | { | ||
556 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | ||
557 | enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; | ||
558 | |||
559 | /* TODO avoid failing a new interface | ||
560 | * creation due to pending removal? | ||
561 | */ | ||
562 | |||
563 | if (!info->attrs[NL802154_ATTR_IFNAME]) | ||
564 | return -EINVAL; | ||
565 | |||
566 | if (info->attrs[NL802154_ATTR_IFTYPE]) { | ||
567 | type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]); | ||
568 | if (type > NL802154_IFTYPE_MAX) | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | if (!rdev->ops->add_virtual_intf) | ||
573 | return -EOPNOTSUPP; | ||
574 | |||
575 | return rdev_add_virtual_intf(rdev, | ||
576 | nla_data(info->attrs[NL802154_ATTR_IFNAME]), | ||
577 | type); | ||
578 | } | ||
579 | |||
554 | static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) | 580 | static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) |
555 | { | 581 | { |
556 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | 582 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; |
@@ -819,6 +845,14 @@ static const struct genl_ops nl802154_ops[] = { | |||
819 | NL802154_FLAG_NEED_RTNL, | 845 | NL802154_FLAG_NEED_RTNL, |
820 | }, | 846 | }, |
821 | { | 847 | { |
848 | .cmd = NL802154_CMD_NEW_INTERFACE, | ||
849 | .doit = nl802154_new_interface, | ||
850 | .policy = nl802154_policy, | ||
851 | .flags = GENL_ADMIN_PERM, | ||
852 | .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | | ||
853 | NL802154_FLAG_NEED_RTNL, | ||
854 | }, | ||
855 | { | ||
822 | .cmd = NL802154_CMD_SET_CHANNEL, | 856 | .cmd = NL802154_CMD_SET_CHANNEL, |
823 | .doit = nl802154_set_channel, | 857 | .doit = nl802154_set_channel, |
824 | .policy = nl802154_policy, | 858 | .policy = nl802154_policy, |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 578bc41e92d3..d3a4f94c5fdc 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
@@ -21,6 +21,13 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, | |||
21 | } | 21 | } |
22 | 22 | ||
23 | static inline int | 23 | static inline int |
24 | rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, | ||
25 | enum nl802154_iftype type) | ||
26 | { | ||
27 | return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type); | ||
28 | } | ||
29 | |||
30 | static inline int | ||
24 | rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) | 31 | rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) |
25 | { | 32 | { |
26 | return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); | 33 | return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); |
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 2abe7e5f0974..ae1a9ef2d42c 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
@@ -43,6 +43,20 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, | |||
43 | } | 43 | } |
44 | 44 | ||
45 | static int | 45 | static int |
46 | ieee802154_add_iface(struct wpan_phy *phy, const char *name, | ||
47 | enum nl802154_iftype type) | ||
48 | { | ||
49 | struct ieee802154_local *local = wpan_phy_priv(phy); | ||
50 | struct net_device *err; | ||
51 | |||
52 | err = ieee802154_if_add(local, name, type); | ||
53 | if (IS_ERR(err)) | ||
54 | return PTR_ERR(err); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int | ||
46 | ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) | 60 | ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) |
47 | { | 61 | { |
48 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); | 62 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); |
@@ -175,6 +189,7 @@ ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, | |||
175 | const struct cfg802154_ops mac802154_config_ops = { | 189 | const struct cfg802154_ops mac802154_config_ops = { |
176 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, | 190 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, |
177 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, | 191 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, |
192 | .add_virtual_intf = ieee802154_add_iface, | ||
178 | .set_channel = ieee802154_set_channel, | 193 | .set_channel = ieee802154_set_channel, |
179 | .set_pan_id = ieee802154_set_pan_id, | 194 | .set_pan_id = ieee802154_set_pan_id, |
180 | .set_short_addr = ieee802154_set_short_addr, | 195 | .set_short_addr = ieee802154_set_short_addr, |