diff options
author | Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> | 2014-02-17 11:34:10 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-17 22:42:38 +0100 |
commit | 84dda3c648fd55898064d76366b14f964cdc9d16 (patch) | |
tree | 5c3f247176a57eedbf854ade71da6f8ff8d7392e /net/ieee802154/nl-phy.c | |
parent | ieee802154: support 100kbps QPSK/EU in at86rf230 (diff) | |
download | linux-84dda3c648fd55898064d76366b14f964cdc9d16.tar.xz linux-84dda3c648fd55898064d76366b14f964cdc9d16.zip |
ieee802154: add support for listen-before-talk in wpan_phy
Listen-before-talk is an alternative to CSMA in uncoordinated networks
and prescribed by european regulations if one wants to have a device
with radio duty cycles above 10% (or less in some bands). Add a phy
property to enable/disable LBT in the phy, including support in the
at86rf230 driver for RF212 chips.
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 | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index d3ee62fbae99..f029310b0662 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -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; |