Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4244db1b authored by Phoebe Buckheister's avatar Phoebe Buckheister Committed by David S. Miller
Browse files

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: default avatarPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7dcbd22a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ enum {
	IEEE802154_ATTR_LBT_ENABLED,
	IEEE802154_ATTR_CCA_MODE,
	IEEE802154_ATTR_CCA_ED_LEVEL,
	IEEE802154_ATTR_CSMA_RETRIES,
	IEEE802154_ATTR_CSMA_MIN_BE,
	IEEE802154_ATTR_CSMA_MAX_BE,

	IEEE802154_ATTR_FRAME_RETRIES,

	__IEEE802154_ATTR_MAX,
};
+12 −0
Original line number Diff line number Diff line
@@ -131,6 +131,14 @@ struct ieee802154_dev {
 *	  Sets the CCA energy detection threshold in dBm. Called with pib_lock
 *	  held.
 *	  Returns either zero, or negative errno.
 *
 * set_csma_params
 *	  Sets the CSMA parameter set for the PHY. Called with pib_lock held.
 *	  Returns either zero, or negative errno.
 *
 * set_frame_retries
 *	  Sets the retransmission attempt limit. Called with pib_lock held.
 *	  Returns either zero, or negative errno.
 */
struct ieee802154_ops {
	struct module	*owner;
@@ -152,6 +160,10 @@ struct ieee802154_ops {
	int		(*set_cca_mode)(struct ieee802154_dev *dev, u8 mode);
	int		(*set_cca_ed_level)(struct ieee802154_dev *dev,
					    s32 level);
	int		(*set_csma_params)(struct ieee802154_dev *dev,
					   u8 min_be, u8 max_be, u8 retries);
	int		(*set_frame_retries)(struct ieee802154_dev *dev,
					     s8 retries);
};

/* Basic interface to register ieee802154 device */
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ struct wpan_phy {
	u32 channels_supported[32];
	s8 transmit_power;
	u8 cca_mode;
	u8 min_be;
	u8 max_be;
	u8 csma_retries;
	s8 frame_retries;

	bool lbt;
	s32 cca_ed_level;
@@ -61,6 +65,9 @@ struct wpan_phy {
	int (*set_lbt)(struct wpan_phy *phy, bool on);
	int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode);
	int (*set_cca_ed_level)(struct wpan_phy *phy, int level);
	int (*set_csma_params)(struct wpan_phy *phy, u8 min_be, u8 max_be,
			       u8 retries);
	int (*set_frame_retries)(struct wpan_phy *phy, s8 retries);

	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
+67 −2
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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, },
};
Loading