|
@@ -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;
|
|
|
+}
|