|
@@ -56,7 +56,8 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
|
|
|
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_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power))
|
|
|
+ nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) ||
|
|
|
+ nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt))
|
|
|
goto nla_put_failure;
|
|
|
for (i = 0; i < 32; i++) {
|
|
|
if (phy->channels_supported[i])
|
|
@@ -356,40 +357,71 @@ out_dev:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int phy_set_txpower(struct wpan_phy *phy, struct genl_info *info)
|
|
|
+{
|
|
|
+ int txpower = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = phy->set_txpower(phy, txpower);
|
|
|
+ if (rc < 0)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ phy->transmit_power = txpower;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int phy_set_lbt(struct wpan_phy *phy, struct genl_info *info)
|
|
|
+{
|
|
|
+ u8 on = !!nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]);
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = phy->set_lbt(phy, on);
|
|
|
+ if (rc < 0)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ phy->lbt = on;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info)
|
|
|
{
|
|
|
struct wpan_phy *phy;
|
|
|
const char *name;
|
|
|
- int txpower;
|
|
|
- int rc = -EINVAL;
|
|
|
+ int rc = -ENOTSUPP;
|
|
|
|
|
|
pr_debug("%s\n", __func__);
|
|
|
|
|
|
- if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
|
|
|
+ if (!info->attrs[IEEE802154_ATTR_PHY_NAME] &&
|
|
|
+ !info->attrs[IEEE802154_ATTR_LBT_ENABLED])
|
|
|
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)
|
|
|
+ if ((!phy->set_txpower && info->attrs[IEEE802154_ATTR_TXPOWER]) ||
|
|
|
+ (!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]))
|
|
|
goto out;
|
|
|
|
|
|
mutex_lock(&phy->pib_lock);
|
|
|
|
|
|
- rc = phy->set_txpower(phy, txpower);
|
|
|
- if (rc < 0) {
|
|
|
- mutex_unlock(&phy->pib_lock);
|
|
|
- goto out;
|
|
|
+ if (info->attrs[IEEE802154_ATTR_TXPOWER]) {
|
|
|
+ rc = phy_set_txpower(phy, info);
|
|
|
+ if (rc < 0)
|
|
|
+ goto error;
|
|
|
}
|
|
|
|
|
|
- phy->transmit_power = txpower;
|
|
|
+ if (info->attrs[IEEE802154_ATTR_LBT_ENABLED]) {
|
|
|
+ rc = phy_set_lbt(phy, info);
|
|
|
+ if (rc < 0)
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
|
|
|
mutex_unlock(&phy->pib_lock);
|
|
|
|
|
@@ -397,6 +429,8 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
+error:
|
|
|
+ mutex_unlock(&phy->pib_lock);
|
|
|
out:
|
|
|
wpan_phy_put(phy);
|
|
|
return rc;
|