aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-02-17 05:34:08 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-17 16:42:38 -0500
commit9b2777d6089bcd7fb035847f907280560fe233c8 (patch)
tree868e579924e3c6cd154996acfef67fb9157e8b26 /net
parent5b520bbb538da7f7122b1e5dc85f2b4c592d4781 (diff)
ieee802154: add TX power control to wpan_phy
Replace the current u8 transmit_power in wpan_phy with s8 transmit_power. The u8 field contained the actual tx power and a tolerance field, which no physical radio every used. Adjust sysfs entries to keep compatibility with userspace, give tolerances of +-1dB statically there. This patch only adds support for this in the at86rf230 driver and the RF212 chip. Configuration calculation for RF212 is also somewhat basic, but does the job - the RF212 datasheet gives a large table with suggested values for combinations of TX power and page/channel, if this does not work well, we might have to copy the whole table. Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ieee802154/ieee802154.h1
-rw-r--r--net/ieee802154/netlink.c1
-rw-r--r--net/ieee802154/nl-phy.c49
-rw-r--r--net/ieee802154/nl_policy.c2
-rw-r--r--net/ieee802154/wpan-class.c4
-rw-r--r--net/mac802154/ieee802154_dev.c11
6 files changed, 64 insertions, 4 deletions
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index cee4425b9956..6cbc8965be91 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -53,6 +53,7 @@ int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
53int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb); 53int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); 54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); 55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
56int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info);
56 57
57enum ieee802154_mcgrp_ids { 58enum ieee802154_mcgrp_ids {
58 IEEE802154_COORD_MCGRP, 59 IEEE802154_COORD_MCGRP,
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 43f1b2bf469f..67c151bf4b91 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -115,6 +115,7 @@ static const struct genl_ops ieee8021154_ops[] = {
115 ieee802154_dump_phy), 115 ieee802154_dump_phy),
116 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface), 116 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
117 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface), 117 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
118 IEEE802154_OP(IEEE802154_SET_PHYPARAMS, ieee802154_set_phyparams),
118 /* see nl-mac.c */ 119 /* see nl-mac.c */
119 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), 120 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
120 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), 121 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 89b265aea151..d3ee62fbae99 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -55,7 +55,8 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
55 mutex_lock(&phy->pib_lock); 55 mutex_lock(&phy->pib_lock);
56 if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || 56 if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
57 nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) || 57 nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) ||
58 nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel)) 58 nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) ||
59 nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power))
59 goto nla_put_failure; 60 goto nla_put_failure;
60 for (i = 0; i < 32; i++) { 61 for (i = 0; i < 32; i++) {
61 if (phy->channels_supported[i]) 62 if (phy->channels_supported[i])
@@ -354,3 +355,49 @@ out_dev:
354 355
355 return rc; 356 return rc;
356} 357}
358
359int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info)
360{
361 struct wpan_phy *phy;
362 const char *name;
363 int txpower;
364 int rc = -EINVAL;
365
366 pr_debug("%s\n", __func__);
367
368 if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
369 return -EINVAL;
370
371 name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
372 if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
373 return -EINVAL; /* phy name should be null-terminated */
374
375 txpower = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
376
377 phy = wpan_phy_find(name);
378 if (!phy)
379 return -ENODEV;
380
381 if (!phy->set_txpower)
382 goto out;
383
384 mutex_lock(&phy->pib_lock);
385
386 rc = phy->set_txpower(phy, txpower);
387 if (rc < 0) {
388 mutex_unlock(&phy->pib_lock);
389 goto out;
390 }
391
392 phy->transmit_power = txpower;
393
394 mutex_unlock(&phy->pib_lock);
395
396 wpan_phy_put(phy);
397
398 return 0;
399
400out:
401 wpan_phy_put(phy);
402 return rc;
403}
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 6adda4d46f95..90b1d0d2c14e 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -52,5 +52,7 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
52 [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, }, 52 [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, },
53 [IEEE802154_ATTR_ED_LIST] = { .len = 27 }, 53 [IEEE802154_ATTR_ED_LIST] = { .len = 27 },
54 [IEEE802154_ATTR_CHANNEL_PAGE_LIST] = { .len = 32 * 4, }, 54 [IEEE802154_ATTR_CHANNEL_PAGE_LIST] = { .len = 32 * 4, },
55
56 [IEEE802154_ATTR_TXPOWER] = { .type = NLA_S8, },
55}; 57};
56 58
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 4dd37615a749..8d6f6704da84 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -44,9 +44,7 @@ static DEVICE_ATTR_RO(name);
44 44
45MASTER_SHOW(current_channel, "%d"); 45MASTER_SHOW(current_channel, "%d");
46MASTER_SHOW(current_page, "%d"); 46MASTER_SHOW(current_page, "%d");
47MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB", 47MASTER_SHOW(transmit_power, "%d +- 1 dB");
48 ((signed char) (phy->transmit_power << 2)) >> 2,
49 (phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1);
50MASTER_SHOW(cca_mode, "%d"); 48MASTER_SHOW(cca_mode, "%d");
51 49
52static ssize_t channels_supported_show(struct device *dev, 50static ssize_t channels_supported_show(struct device *dev,
diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c
index 52ae6646a411..9eb49e0886a4 100644
--- a/net/mac802154/ieee802154_dev.c
+++ b/net/mac802154/ieee802154_dev.c
@@ -165,6 +165,16 @@ err:
165 return ERR_PTR(err); 165 return ERR_PTR(err);
166} 166}
167 167
168static int mac802154_set_txpower(struct wpan_phy *phy, int db)
169{
170 struct mac802154_priv *priv = wpan_phy_priv(phy);
171
172 if (!priv->ops->set_txpower)
173 return -ENOTSUPP;
174
175 return priv->ops->set_txpower(&priv->hw, db);
176}
177
168struct ieee802154_dev * 178struct ieee802154_dev *
169ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) 179ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops)
170{ 180{
@@ -242,6 +252,7 @@ int ieee802154_register_device(struct ieee802154_dev *dev)
242 252
243 priv->phy->add_iface = mac802154_add_iface; 253 priv->phy->add_iface = mac802154_add_iface;
244 priv->phy->del_iface = mac802154_del_iface; 254 priv->phy->del_iface = mac802154_del_iface;
255 priv->phy->set_txpower = mac802154_set_txpower;
245 256
246 rc = wpan_phy_register(priv->phy); 257 rc = wpan_phy_register(priv->phy);
247 if (rc < 0) 258 if (rc < 0)