diff options
author | Varka Bhadram <varkabhadram@gmail.com> | 2015-05-26 23:40:54 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-05-27 07:29:25 -0400 |
commit | 0f999b09f5c1b135e840501840dbcd01fad66f79 (patch) | |
tree | 1f632df3dee5995e7a0f4b39b7dc4739b54f5702 | |
parent | fc4f80524368dbf3fa2eba639c7b79bb014aea0a (diff) |
ieee802154: add set transmit power support
This patch adds transmission power setting support for IEEE-802.15.4
devices via nl802154.
Signed-off-by: Varka Bhadram <varkab@cdac.in>
Acked-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 | 30 | ||||
-rw-r--r-- | net/ieee802154/rdev-ops.h | 12 | ||||
-rw-r--r-- | net/ieee802154/trace.h | 15 | ||||
-rw-r--r-- | net/mac802154/cfg.c | 19 |
5 files changed, 77 insertions, 0 deletions
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 4de59aa96173..2e3bb012c2ff 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h | |||
@@ -44,6 +44,7 @@ struct cfg802154_ops { | |||
44 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); | 44 | int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); |
45 | int (*set_cca_mode)(struct wpan_phy *wpan_phy, | 45 | int (*set_cca_mode)(struct wpan_phy *wpan_phy, |
46 | const struct wpan_phy_cca *cca); | 46 | const struct wpan_phy_cca *cca); |
47 | int (*set_tx_power)(struct wpan_phy *wpan_phy, s32 power); | ||
47 | int (*set_pan_id)(struct wpan_phy *wpan_phy, | 48 | int (*set_pan_id)(struct wpan_phy *wpan_phy, |
48 | struct wpan_dev *wpan_dev, __le16 pan_id); | 49 | struct wpan_dev *wpan_dev, __le16 pan_id); |
49 | int (*set_short_addr)(struct wpan_phy *wpan_phy, | 50 | int (*set_short_addr)(struct wpan_phy *wpan_phy, |
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 212a795b33c9..5c9d524ba02c 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c | |||
@@ -783,6 +783,28 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info) | |||
783 | return rdev_set_cca_mode(rdev, &cca); | 783 | return rdev_set_cca_mode(rdev, &cca); |
784 | } | 784 | } |
785 | 785 | ||
786 | static int nl802154_set_tx_power(struct sk_buff *skb, struct genl_info *info) | ||
787 | { | ||
788 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | ||
789 | s32 power; | ||
790 | int i; | ||
791 | |||
792 | if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER)) | ||
793 | return -EOPNOTSUPP; | ||
794 | |||
795 | if (!info->attrs[NL802154_ATTR_TX_POWER]) | ||
796 | return -EINVAL; | ||
797 | |||
798 | power = nla_get_s32(info->attrs[NL802154_ATTR_TX_POWER]); | ||
799 | |||
800 | for (i = 0; i < rdev->wpan_phy.supported.tx_powers_size; i++) { | ||
801 | if (power == rdev->wpan_phy.supported.tx_powers[i]) | ||
802 | return rdev_set_tx_power(rdev, power); | ||
803 | } | ||
804 | |||
805 | return -EINVAL; | ||
806 | } | ||
807 | |||
786 | static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) | 808 | static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) |
787 | { | 809 | { |
788 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; | 810 | struct cfg802154_registered_device *rdev = info->user_ptr[0]; |
@@ -1094,6 +1116,14 @@ static const struct genl_ops nl802154_ops[] = { | |||
1094 | NL802154_FLAG_NEED_RTNL, | 1116 | NL802154_FLAG_NEED_RTNL, |
1095 | }, | 1117 | }, |
1096 | { | 1118 | { |
1119 | .cmd = NL802154_CMD_SET_TX_POWER, | ||
1120 | .doit = nl802154_set_tx_power, | ||
1121 | .policy = nl802154_policy, | ||
1122 | .flags = GENL_ADMIN_PERM, | ||
1123 | .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | | ||
1124 | NL802154_FLAG_NEED_RTNL, | ||
1125 | }, | ||
1126 | { | ||
1097 | .cmd = NL802154_CMD_SET_PAN_ID, | 1127 | .cmd = NL802154_CMD_SET_PAN_ID, |
1098 | .doit = nl802154_set_pan_id, | 1128 | .doit = nl802154_set_pan_id, |
1099 | .policy = nl802154_policy, | 1129 | .policy = nl802154_policy, |
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 7b5a9dd94fe5..36456118a6ec 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h | |||
@@ -75,6 +75,18 @@ rdev_set_cca_mode(struct cfg802154_registered_device *rdev, | |||
75 | } | 75 | } |
76 | 76 | ||
77 | static inline int | 77 | static inline int |
78 | rdev_set_tx_power(struct cfg802154_registered_device *rdev, | ||
79 | s32 power) | ||
80 | { | ||
81 | int ret; | ||
82 | |||
83 | trace_802154_rdev_set_tx_power(&rdev->wpan_phy, power); | ||
84 | ret = rdev->ops->set_tx_power(&rdev->wpan_phy, power); | ||
85 | trace_802154_rdev_return_int(&rdev->wpan_phy, ret); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static inline int | ||
78 | rdev_set_pan_id(struct cfg802154_registered_device *rdev, | 90 | rdev_set_pan_id(struct cfg802154_registered_device *rdev, |
79 | struct wpan_dev *wpan_dev, __le16 pan_id) | 91 | struct wpan_dev *wpan_dev, __le16 pan_id) |
80 | { | 92 | { |
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h index 5ac25eb6ed17..1f1cecc420d7 100644 --- a/net/ieee802154/trace.h +++ b/net/ieee802154/trace.h | |||
@@ -93,6 +93,21 @@ TRACE_EVENT(802154_rdev_set_channel, | |||
93 | __entry->page, __entry->channel) | 93 | __entry->page, __entry->channel) |
94 | ); | 94 | ); |
95 | 95 | ||
96 | TRACE_EVENT(802154_rdev_set_tx_power, | ||
97 | TP_PROTO(struct wpan_phy *wpan_phy, s32 power), | ||
98 | TP_ARGS(wpan_phy, power), | ||
99 | TP_STRUCT__entry( | ||
100 | WPAN_PHY_ENTRY | ||
101 | __field(s32, power) | ||
102 | ), | ||
103 | TP_fast_assign( | ||
104 | WPAN_PHY_ASSIGN; | ||
105 | __entry->power = power; | ||
106 | ), | ||
107 | TP_printk(WPAN_PHY_PR_FMT ", power: %d", WPAN_PHY_PR_ARG, | ||
108 | __entry->power) | ||
109 | ); | ||
110 | |||
96 | TRACE_EVENT(802154_rdev_set_cca_mode, | 111 | TRACE_EVENT(802154_rdev_set_cca_mode, |
97 | TP_PROTO(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca), | 112 | TP_PROTO(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca), |
98 | TP_ARGS(wpan_phy, cca), | 113 | TP_ARGS(wpan_phy, cca), |
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index d5290ea49dca..ab12fa296eb3 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c | |||
@@ -106,6 +106,24 @@ ieee802154_set_cca_mode(struct wpan_phy *wpan_phy, | |||
106 | } | 106 | } |
107 | 107 | ||
108 | static int | 108 | static int |
109 | ieee802154_set_tx_power(struct wpan_phy *wpan_phy, s32 power) | ||
110 | { | ||
111 | struct ieee802154_local *local = wpan_phy_priv(wpan_phy); | ||
112 | int ret; | ||
113 | |||
114 | ASSERT_RTNL(); | ||
115 | |||
116 | if (wpan_phy->transmit_power == power) | ||
117 | return 0; | ||
118 | |||
119 | ret = drv_set_tx_power(local, power); | ||
120 | if (!ret) | ||
121 | wpan_phy->transmit_power = power; | ||
122 | |||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static int | ||
109 | ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, | 127 | ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, |
110 | __le16 pan_id) | 128 | __le16 pan_id) |
111 | { | 129 | { |
@@ -195,6 +213,7 @@ const struct cfg802154_ops mac802154_config_ops = { | |||
195 | .del_virtual_intf = ieee802154_del_iface, | 213 | .del_virtual_intf = ieee802154_del_iface, |
196 | .set_channel = ieee802154_set_channel, | 214 | .set_channel = ieee802154_set_channel, |
197 | .set_cca_mode = ieee802154_set_cca_mode, | 215 | .set_cca_mode = ieee802154_set_cca_mode, |
216 | .set_tx_power = ieee802154_set_tx_power, | ||
198 | .set_pan_id = ieee802154_set_pan_id, | 217 | .set_pan_id = ieee802154_set_pan_id, |
199 | .set_short_addr = ieee802154_set_short_addr, | 218 | .set_short_addr = ieee802154_set_short_addr, |
200 | .set_backoff_exponent = ieee802154_set_backoff_exponent, | 219 | .set_backoff_exponent = ieee802154_set_backoff_exponent, |