aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVarka Bhadram <varkabhadram@gmail.com>2015-05-26 23:40:54 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-05-27 07:29:25 -0400
commit0f999b09f5c1b135e840501840dbcd01fad66f79 (patch)
tree1f632df3dee5995e7a0f4b39b7dc4739b54f5702
parentfc4f80524368dbf3fa2eba639c7b79bb014aea0a (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.h1
-rw-r--r--net/ieee802154/nl802154.c30
-rw-r--r--net/ieee802154/rdev-ops.h12
-rw-r--r--net/ieee802154/trace.h15
-rw-r--r--net/mac802154/cfg.c19
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
786static 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
786static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) 808static 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
77static inline int 77static inline int
78rdev_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
89static inline int
78rdev_set_pan_id(struct cfg802154_registered_device *rdev, 90rdev_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
96TRACE_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
96TRACE_EVENT(802154_rdev_set_cca_mode, 111TRACE_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
108static int 108static int
109ieee802154_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
126static int
109ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, 127ieee802154_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,