From 4244db1b0b7bc9ab7b67d8c1c38de6cf15bc87a8 Mon Sep 17 00:00:00 2001 From: Phoebe Buckheister Date: Mon, 17 Feb 2014 11:34:14 +0100 Subject: ieee802154: add netlink APIs for smartMAC configuration Introduce new netlink attributes for SET_PHY_ATTRS: * CSMA minimal backoff exponent * CSMA maximal backoff exponent * CSMA retry limit * frame retransmission limit The CSMA attributes shall correspond to minBE, maxBE and maxCSMABackoffs of 802.15.4, respectively. The frame retransmission shall correspond to maxFrameRetries of 802.15.4, unless given as -1: then the old behaviour of the stack shall apply. For RF2xy, the old behaviour is to not do channel sensing at all and simply send *right now*, which is not intended behaviour for most applications and actually prohibited for some channel/page combinations. For all values except frame retransmission limit, the defaults of 802.15.4 apply. Frame retransmission limits are set to -1 to indicate backward-compatible behaviour. Signed-off-by: Phoebe Buckheister Signed-off-by: David S. Miller --- net/ieee802154/nl-phy.c | 69 +++++++++++++++++++++++++++++++++++++++++++-- net/ieee802154/nl_policy.c | 5 ++++ net/ieee802154/wpan-class.c | 6 ++++ 3 files changed, 78 insertions(+), 2 deletions(-) (limited to 'net/ieee802154') diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 0af0d42..c9dfd6f 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -59,7 +59,11 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) || nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) || nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, phy->cca_mode) || - nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL, phy->cca_ed_level)) + nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL, phy->cca_ed_level) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_RETRIES, phy->csma_retries) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_MIN_BE, phy->min_be) || + nla_put_u8(msg, IEEE802154_ATTR_CSMA_MAX_BE, phy->max_be) || + nla_put_s8(msg, IEEE802154_ATTR_FRAME_RETRIES, phy->frame_retries)) goto nla_put_failure; for (i = 0; i < 32; i++) { if (phy->channels_supported[i]) @@ -418,6 +422,49 @@ static int phy_set_cca_ed_level(struct wpan_phy *phy, struct genl_info *info) return 0; } +static int phy_set_csma_params(struct wpan_phy *phy, struct genl_info *info) +{ + int rc; + u8 min_be = phy->min_be; + u8 max_be = phy->max_be; + u8 retries = phy->csma_retries; + + if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES]) + retries = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_RETRIES]); + if (info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]) + min_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]); + if (info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]) + max_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]); + + if (retries > 5 || max_be > 8 || min_be > max_be || + retries < -1 || retries > 7) + return -EINVAL; + + rc = phy->set_csma_params(phy, min_be, max_be, retries); + if (rc < 0) + return rc; + + phy->min_be = min_be; + phy->max_be = max_be; + phy->csma_retries = retries; + + return 0; +} + +static int phy_set_frame_retries(struct wpan_phy *phy, struct genl_info *info) +{ + s8 retries = nla_get_s8(info->attrs[IEEE802154_ATTR_FRAME_RETRIES]); + int rc; + + rc = phy->set_frame_retries(phy, retries); + if (rc < 0) + return rc; + + phy->frame_retries = retries; + + return 0; +} + int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) { struct wpan_phy *phy; @@ -429,7 +476,11 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[IEEE802154_ATTR_PHY_NAME] && !info->attrs[IEEE802154_ATTR_LBT_ENABLED] && !info->attrs[IEEE802154_ATTR_CCA_MODE] && - !info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) + !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]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); @@ -473,6 +524,20 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) goto error; } + if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] || + info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] || + info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]) { + rc = phy_set_csma_params(phy, info); + if (rc < 0) + goto error; + } + + if (info->attrs[IEEE802154_ATTR_FRAME_RETRIES]) { + rc = phy_set_frame_retries(phy, info); + if (rc < 0) + goto error; + } + mutex_unlock(&phy->pib_lock); wpan_phy_put(phy); diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c index 55b5616..fd7be5e 100644 --- a/net/ieee802154/nl_policy.c +++ b/net/ieee802154/nl_policy.c @@ -57,5 +57,10 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { [IEEE802154_ATTR_LBT_ENABLED] = { .type = NLA_U8, }, [IEEE802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, [IEEE802154_ATTR_CCA_ED_LEVEL] = { .type = NLA_S32, }, + [IEEE802154_ATTR_CSMA_RETRIES] = { .type = NLA_U8, }, + [IEEE802154_ATTR_CSMA_MIN_BE] = { .type = NLA_U8, }, + [IEEE802154_ATTR_CSMA_MAX_BE] = { .type = NLA_U8, }, + + [IEEE802154_ATTR_FRAME_RETRIES] = { .type = NLA_S8, }, }; diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 8d6f670..edd0962 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -169,6 +169,12 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size) phy->current_channel = -1; /* not initialised */ phy->current_page = 0; /* for compatibility */ + /* defaults per 802.15.4-2011 */ + phy->min_be = 3; + phy->max_be = 5; + phy->csma_retries = 4; + phy->frame_retries = -1; /* for compatibility, actual default is 3 */ + return phy; out: -- cgit v1.1