diff options
author | Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> | 2014-02-17 11:34:08 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-17 16:42:38 -0500 |
commit | 9b2777d6089bcd7fb035847f907280560fe233c8 (patch) | |
tree | 868e579924e3c6cd154996acfef67fb9157e8b26 /net/ieee802154/nl-phy.c | |
parent | 5b520bbb538da7f7122b1e5dc85f2b4c592d4781 (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/ieee802154/nl-phy.c')
-rw-r--r-- | net/ieee802154/nl-phy.c | 49 |
1 files changed, 48 insertions, 1 deletions
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, mutex_lock(&phy->pib_lock); if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) || - nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel)) + nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) || + nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power)) goto nla_put_failure; for (i = 0; i < 32; i++) { if (phy->channels_supported[i]) @@ -354,3 +355,49 @@ out_dev: return rc; } + +int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) +{ + struct wpan_phy *phy; + const char *name; + int txpower; + int rc = -EINVAL; + + pr_debug("%s\n", __func__); + + if (!info->attrs[IEEE802154_ATTR_PHY_NAME]) + return -EINVAL; + + name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); + if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') + return -EINVAL; /* phy name should be null-terminated */ + + txpower = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]); + + phy = wpan_phy_find(name); + if (!phy) + return -ENODEV; + + if (!phy->set_txpower) + goto out; + + mutex_lock(&phy->pib_lock); + + rc = phy->set_txpower(phy, txpower); + if (rc < 0) { + mutex_unlock(&phy->pib_lock); + goto out; + } + + phy->transmit_power = txpower; + + mutex_unlock(&phy->pib_lock); + + wpan_phy_put(phy); + + return 0; + +out: + wpan_phy_put(phy); + return rc; +} |