diff options
author | Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> | 2014-03-31 21:37:46 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-01 22:25:51 +0200 |
commit | e462ded699aa2cca04b68fbf203ea4675d4c44d4 (patch) | |
tree | 4c7b2f9d1e456acad01eb052f2dfa7d8533d92d8 /net/ieee802154/nl-mac.c | |
parent | mac802154: allow only one WPAN to be up at any given time (diff) | |
download | linux-e462ded699aa2cca04b68fbf203ea4675d4c44d4.tar.xz linux-e462ded699aa2cca04b68fbf203ea4675d4c44d4.zip |
mac802154: make csma/cca parameters per-wpan
Commit 9b2777d6089bcd (ieee802154: add TX power control to wpan_phy)
and following erroneously added CSMA and CCA parameters for 802.15.4
devices as PHY parameters, while they are actually MAC parameters and
can differ for any two WPAN instances. Since it is now sensible to have
multiple WPAN devices with differing CSMA/CCA parameters, make these
parameters MAC parameters instead.
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-mac.c')
-rw-r--r-- | net/ieee802154/nl-mac.c | 122 |
1 files changed, 119 insertions, 3 deletions
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index bda8dba4f993..5d285498c0f6 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -264,6 +264,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid, { void *hdr; struct wpan_phy *phy; + struct ieee802154_mlme_ops *ops; __le16 short_addr, pan_id; pr_debug("%s\n", __func__); @@ -273,11 +274,12 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid, if (!hdr) goto out; - phy = ieee802154_mlme_ops(dev)->get_phy(dev); + ops = ieee802154_mlme_ops(dev); + phy = ops->get_phy(dev); BUG_ON(!phy); - short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); - pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); + short_addr = ops->get_short_addr(dev); + pan_id = ops->get_pan_id(dev); if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) || nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || @@ -287,6 +289,30 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid, nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id)) goto nla_put_failure; + + if (ops->get_mac_params) { + struct ieee802154_mac_params params; + + ops->get_mac_params(dev, ¶ms); + + if (nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, + params.transmit_power) || + nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, params.lbt) || + nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, + params.cca_mode) || + nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL, + params.cca_ed_level) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_RETRIES, + params.csma_retries) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_MIN_BE, + params.min_be) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_MAX_BE, + params.max_be) || + nla_put_s8(msg, IEEE802154_ATTR_FRAME_RETRIES, + params.frame_retries)) + goto nla_put_failure; + } + wpan_phy_put(phy); return genlmsg_end(msg, hdr); @@ -599,3 +625,93 @@ cont: return skb->len; } + +int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) +{ + struct net_device *dev = NULL; + struct ieee802154_mlme_ops *ops; + struct ieee802154_mac_params params; + struct wpan_phy *phy; + int rc = -EINVAL; + + pr_debug("%s\n", __func__); + + dev = ieee802154_nl_get_dev(info); + if (!dev) + return -ENODEV; + + ops = ieee802154_mlme_ops(dev); + + if (!ops->get_mac_params || !ops->set_mac_params) { + rc = -EOPNOTSUPP; + goto out; + } + + if (netif_running(dev)) { + rc = -EBUSY; + goto out; + } + + if (!info->attrs[IEEE802154_ATTR_LBT_ENABLED] && + !info->attrs[IEEE802154_ATTR_CCA_MODE] && + !info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL] && + !info->attrs[IEEE802154_ATTR_CSMA_RETRIES] && + !info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] && + !info->attrs[IEEE802154_ATTR_CSMA_MAX_BE] && + !info->attrs[IEEE802154_ATTR_FRAME_RETRIES]) + goto out; + + phy = ops->get_phy(dev); + + if ((!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) || + (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) || + (!phy->set_cca_ed_level && + info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) || + (!phy->set_csma_params && + (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] || + info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] || + info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])) || + (!phy->set_frame_retries && + info->attrs[IEEE802154_ATTR_FRAME_RETRIES])) { + rc = -EOPNOTSUPP; + goto out_phy; + } + + ops->get_mac_params(dev, ¶ms); + + if (info->attrs[IEEE802154_ATTR_TXPOWER]) + params.transmit_power = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]); + + if (info->attrs[IEEE802154_ATTR_LBT_ENABLED]) + params.lbt = nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]); + + if (info->attrs[IEEE802154_ATTR_CCA_MODE]) + params.cca_mode = nla_get_u8(info->attrs[IEEE802154_ATTR_CCA_MODE]); + + if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) + params.cca_ed_level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]); + + if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES]) + params.csma_retries = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_RETRIES]); + + if (info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]) + params.min_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]); + + if (info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]) + params.max_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]); + + if (info->attrs[IEEE802154_ATTR_FRAME_RETRIES]) + params.frame_retries = nla_get_s8(info->attrs[IEEE802154_ATTR_FRAME_RETRIES]); + + rc = ops->set_mac_params(dev, ¶ms); + + wpan_phy_put(phy); + dev_put(dev); + return rc; + +out_phy: + wpan_phy_put(phy); +out: + dev_put(dev); + return rc; +} |