summaryrefslogtreecommitdiffstats
path: root/net/ieee802154/nl-phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154/nl-phy.c')
-rw-r--r--net/ieee802154/nl-phy.c49
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;
+}