diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-11-11 21:36:55 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-11-11 23:10:38 -0500 |
commit | ab0bd561724bf3c09aa80e76ca0a187c6880bc5c (patch) | |
tree | 0a76f4758dab960dbee5ab1f8577bd452adb948b | |
parent | 9d30a8cf98b2dd132d6e4503718df78ffc1b7f53 (diff) |
ieee820154: add channel set support
This patch adds page and channel setting support to nl802154 framework.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | include/net/cfg802154.h | 1 | ||||
-rw-r--r-- | net/ieee802154/nl802154.c | 28 | ||||
-rw-r--r-- | net/ieee802154/rdev-ops.h | 7 | ||||
-rw-r--r-- | net/mac802154/cfg.c | 24 |
4 files changed, 60 insertions, 0 deletions
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 8a3edc5edad1..391fdb37208d 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h | |||
@@ -37,6 +37,7 @@ struct cfg802154_ops { | |||
37 | int type); | 37 | int type); |
38 | void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, | 38 | void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, |
39 | struct net_device *dev); | 39 | struct net_device *dev); |
40 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | struct wpan_phy { | 43 | struct wpan_phy { |
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 46df7dca92d9..d8ef2c8a182f 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <net/sock.h> | 23 | #include <net/sock.h> |
24 | 24 | ||
25 | #include "nl802154.h" | 25 | #include "nl802154.h" |
26 | #include "rdev-ops.h" | ||
26 | #include "core.h" | 27 | #include "core.h" |
27 | 28 | ||
28 | static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, | 29 | static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
@@ -550,6 +551,25 @@ static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
550 | return genlmsg_reply(msg, info); | 551 | return genlmsg_reply(msg, info); |
551 | } | 552 | } |
552 | 553 | ||
554 | static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) | ||
555 | { | ||
556 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | ||
557 | u8 channel, page; | ||
558 | |||
559 | if (!info->attrs[NL802154_ATTR_PAGE] || | ||
560 | !info->attrs[NL802154_ATTR_CHANNEL]) | ||
561 | return -EINVAL; | ||
562 | |||
563 | page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]); | ||
564 | channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]); | ||
565 | |||
566 | /* check 802.15.4 constraints */ | ||
567 | if (page >= WPAN_NUM_PAGES || channel >= WPAN_NUM_CHANNELS) | ||
568 | return -EINVAL; | ||
569 | |||
570 | return rdev_set_channel(rdev, page, channel); | ||
571 | } | ||
572 | |||
553 | #define NL802154_FLAG_NEED_WPAN_PHY 0x01 | 573 | #define NL802154_FLAG_NEED_WPAN_PHY 0x01 |
554 | #define NL802154_FLAG_NEED_NETDEV 0x02 | 574 | #define NL802154_FLAG_NEED_NETDEV 0x02 |
555 | #define NL802154_FLAG_NEED_RTNL 0x04 | 575 | #define NL802154_FLAG_NEED_RTNL 0x04 |
@@ -660,6 +680,14 @@ static const struct genl_ops nl802154_ops[] = { | |||
660 | .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | | 680 | .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | |
661 | NL802154_FLAG_NEED_RTNL, | 681 | NL802154_FLAG_NEED_RTNL, |
662 | }, | 682 | }, |
683 | { | ||
684 | .cmd = NL802154_CMD_SET_CHANNEL, | ||
685 | .doit = nl802154_set_channel, | ||
686 | .policy = nl802154_policy, | ||
687 | .flags = GENL_ADMIN_PERM, | ||
688 | .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | | ||
689 | NL802154_FLAG_NEED_RTNL, | ||
690 | }, | ||
663 | }; | 691 | }; |
664 | 692 | ||
665 | /* initialisation/exit functions */ | 693 | /* initialisation/exit functions */ |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index ac8824ec168c..8a3b0eb4e026 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
@@ -20,4 +20,11 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, | |||
20 | rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev); | 20 | rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev); |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline int | ||
24 | rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page, | ||
25 | const u8 channel) | ||
26 | { | ||
27 | return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); | ||
28 | } | ||
29 | |||
23 | #endif /* __CFG802154_RDEV_OPS */ | 30 | #endif /* __CFG802154_RDEV_OPS */ |
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index d2c4e8f89720..9d5b1895c752 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <net/cfg802154.h> | 17 | #include <net/cfg802154.h> |
18 | 18 | ||
19 | #include "ieee802154_i.h" | 19 | #include "ieee802154_i.h" |
20 | #include "driver-ops.h" | ||
20 | #include "cfg.h" | 21 | #include "cfg.h" |
21 | 22 | ||
22 | static struct net_device * | 23 | static struct net_device * |
@@ -41,7 +42,30 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, | |||
41 | ieee802154_if_remove(sdata); | 42 | ieee802154_if_remove(sdata); |
42 | } | 43 | } |
43 | 44 | ||
45 | static int | ||
46 | ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page, | ||
47 | const u8 channel) | ||
48 | { | ||
49 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); | ||
50 | int ret; | ||
51 | |||
52 | ASSERT_RTNL(); | ||
53 | |||
54 | /* check if phy support this setting */ | ||
55 | if (!(wpan_phy->channels_supported[page] & BIT(channel))) | ||
56 | return -EINVAL; | ||
57 | |||
58 | ret = drv_set_channel(local, page, channel); | ||
59 | if (!ret) { | ||
60 | wpan_phy->current_page = page; | ||
61 | wpan_phy->current_channel = channel; | ||
62 | } | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
44 | const struct cfg802154_ops mac802154_config_ops = { | 67 | const struct cfg802154_ops mac802154_config_ops = { |
45 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, | 68 | .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, |
46 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, | 69 | .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, |
70 | .set_channel = ieee802154_set_channel, | ||
47 | }; | 71 | }; |