diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-12-10 09:33:13 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-18 18:19:23 -0500 |
commit | ba2a9506a76450568cbc0d51626d94cf8528c0c7 (patch) | |
tree | 71f548777d889121041d978c7806db22b04235d1 /net/ieee802154 | |
parent | 7fe9a3882bb37195c41ab125a0f2852398d2646a (diff) |
nl802154: introduce support for cca settings
This patch adds support for setting cca parameters via nl802154.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/nl802154.c | 46 | ||||
-rw-r--r-- | net/ieee802154/rdev-ops.h | 7 |
2 files changed, 50 insertions, 3 deletions
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 1efbe4250024..a25b9bbd077b 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
@@ -209,7 +209,8 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { | |||
209 | 209 | ||
210 | [NL802154_ATTR_TX_POWER] = { .type = NLA_S8, }, | 210 | [NL802154_ATTR_TX_POWER] = { .type = NLA_S8, }, |
211 | 211 | ||
212 | [NL802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, | 212 | [NL802154_ATTR_CCA_MODE] = { .type = NLA_U32, }, |
213 | [NL802154_ATTR_CCA_OPT] = { .type = NLA_U32, }, | ||
213 | 214 | ||
214 | [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, | 215 | [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, |
215 | 216 | ||
@@ -290,10 +291,16 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev, | |||
290 | goto nla_put_failure; | 291 | goto nla_put_failure; |
291 | 292 | ||
292 | /* cca mode */ | 293 | /* cca mode */ |
293 | if (nla_put_u8(msg, NL802154_ATTR_CCA_MODE, | 294 | if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE, |
294 | rdev->wpan_phy.cca.mode)) | 295 | rdev->wpan_phy.cca.mode)) |
295 | goto nla_put_failure; | 296 | goto nla_put_failure; |
296 | 297 | ||
298 | if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) { | ||
299 | if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT, | ||
300 | rdev->wpan_phy.cca.opt)) | ||
301 | goto nla_put_failure; | ||
302 | } | ||
303 | |||
297 | if (nla_put_s8(msg, NL802154_ATTR_TX_POWER, | 304 | if (nla_put_s8(msg, NL802154_ATTR_TX_POWER, |
298 | rdev->wpan_phy.transmit_power)) | 305 | rdev->wpan_phy.transmit_power)) |
299 | goto nla_put_failure; | 306 | goto nla_put_failure; |
@@ -622,6 +629,31 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) | |||
622 | return rdev_set_channel(rdev, page, channel); | 629 | return rdev_set_channel(rdev, page, channel); |
623 | } | 630 | } |
624 | 631 | ||
632 | static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info) | ||
633 | { | ||
634 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | ||
635 | struct wpan_phy_cca cca; | ||
636 | |||
637 | if (!info->attrs[NL802154_ATTR_CCA_MODE]) | ||
638 | return -EINVAL; | ||
639 | |||
640 | cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]); | ||
641 | /* checking 802.15.4 constraints */ | ||
642 | if (cca.mode < NL802154_CCA_ENERGY || cca.mode > NL802154_CCA_ATTR_MAX) | ||
643 | return -EINVAL; | ||
644 | |||
645 | if (cca.mode == NL802154_CCA_ENERGY_CARRIER) { | ||
646 | if (!info->attrs[NL802154_ATTR_CCA_OPT]) | ||
647 | return -EINVAL; | ||
648 | |||
649 | cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]); | ||
650 | if (cca.opt > NL802154_CCA_OPT_ATTR_MAX) | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | |||
654 | return rdev_set_cca_mode(rdev, &cca); | ||
655 | } | ||
656 | |||
625 | static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) | 657 | static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) |
626 | { | 658 | { |
627 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | 659 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; |
@@ -895,6 +927,14 @@ static const struct genl_ops nl802154_ops[] = { | |||
895 | NL802154_FLAG_NEED_RTNL, | 927 | NL802154_FLAG_NEED_RTNL, |
896 | }, | 928 | }, |
897 | { | 929 | { |
930 | .cmd = NL802154_CMD_SET_CCA_MODE, | ||
931 | .doit = nl802154_set_cca_mode, | ||
932 | .policy = nl802154_policy, | ||
933 | .flags = GENL_ADMIN_PERM, | ||
934 | .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | | ||
935 | NL802154_FLAG_NEED_RTNL, | ||
936 | }, | ||
937 | { | ||
898 | .cmd = NL802154_CMD_SET_PAN_ID, | 938 | .cmd = NL802154_CMD_SET_PAN_ID, |
899 | .doit = nl802154_set_pan_id, | 939 | .doit = nl802154_set_pan_id, |
900 | .policy = nl802154_policy, | 940 | .policy = nl802154_policy, |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index aff54fbd9264..7c46732fad2b 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
@@ -42,6 +42,13 @@ rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) | |||
42 | } | 42 | } |
43 | 43 | ||
44 | static inline int | 44 | static inline int |
45 | rdev_set_cca_mode(struct cfg802154_registered_device *rdev, | ||
46 | const struct wpan_phy_cca *cca) | ||
47 | { | ||
48 | return rdev->ops->set_cca_mode(&rdev->wpan_phy, cca); | ||
49 | } | ||
50 | |||
51 | static inline int | ||
45 | rdev_set_pan_id(struct cfg802154_registered_device *rdev, | 52 | rdev_set_pan_id(struct cfg802154_registered_device *rdev, |
46 | struct wpan_dev *wpan_dev, __le16 pan_id) | 53 | struct wpan_dev *wpan_dev, __le16 pan_id) |
47 | { | 54 | { |