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

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

mac802154: make csma/cca parameters per-wpan



Commit 9b2777d6 (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: default avatarPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 336908f6
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -132,7 +132,7 @@ enum {
	IEEE802154_ADD_IFACE,
	IEEE802154_ADD_IFACE,
	IEEE802154_DEL_IFACE,
	IEEE802154_DEL_IFACE,


	IEEE802154_SET_PHYPARAMS,
	IEEE802154_SET_MACPARAMS,


	__IEEE802154_CMD_MAX,
	__IEEE802154_CMD_MAX,
};
};
+17 −0
Original line number Original line Diff line number Diff line
@@ -229,6 +229,18 @@ static inline int mac_cb_type(struct sk_buff *skb)
#define IEEE802154_MAC_SCAN_PASSIVE	2
#define IEEE802154_MAC_SCAN_PASSIVE	2
#define IEEE802154_MAC_SCAN_ORPHAN	3
#define IEEE802154_MAC_SCAN_ORPHAN	3


struct ieee802154_mac_params {
	s8 transmit_power;
	u8 min_be;
	u8 max_be;
	u8 csma_retries;
	s8 frame_retries;

	bool lbt;
	u8 cca_mode;
	s32 cca_ed_level;
};

struct wpan_phy;
struct wpan_phy;
/*
/*
 * This should be located at net_device->ml_priv
 * This should be located at net_device->ml_priv
@@ -255,6 +267,11 @@ struct ieee802154_mlme_ops {
	int (*scan_req)(struct net_device *dev,
	int (*scan_req)(struct net_device *dev,
			u8 type, u32 channels, u8 page, u8 duration);
			u8 type, u32 channels, u8 page, u8 duration);


	int (*set_mac_params)(struct net_device *dev,
			      const struct ieee802154_mac_params *params);
	void (*get_mac_params)(struct net_device *dev,
			       struct ieee802154_mac_params *params);

	/* The fields below are required. */
	/* The fields below are required. */


	struct wpan_phy *(*get_phy)(const struct net_device *dev);
	struct wpan_phy *(*get_phy)(const struct net_device *dev);
+1 −1
Original line number Original line Diff line number Diff line
@@ -53,7 +53,6 @@ int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info);


enum ieee802154_mcgrp_ids {
enum ieee802154_mcgrp_ids {
	IEEE802154_COORD_MCGRP,
	IEEE802154_COORD_MCGRP,
@@ -67,5 +66,6 @@ int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info);


#endif
#endif
+1 −1
Original line number Original line Diff line number Diff line
@@ -115,7 +115,6 @@ static const struct genl_ops ieee8021154_ops[] = {
			ieee802154_dump_phy),
			ieee802154_dump_phy),
	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
	IEEE802154_OP(IEEE802154_SET_PHYPARAMS, ieee802154_set_phyparams),
	/* see nl-mac.c */
	/* see nl-mac.c */
	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
@@ -124,6 +123,7 @@ static const struct genl_ops ieee8021154_ops[] = {
	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
			ieee802154_dump_iface),
			ieee802154_dump_iface),
	IEEE802154_OP(IEEE802154_SET_MACPARAMS, ieee802154_set_macparams),
};
};


static const struct genl_multicast_group ieee802154_mcgrps[] = {
static const struct genl_multicast_group ieee802154_mcgrps[] = {
+119 −3
Original line number Original line Diff line number Diff line
@@ -264,6 +264,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
{
{
	void *hdr;
	void *hdr;
	struct wpan_phy *phy;
	struct wpan_phy *phy;
	struct ieee802154_mlme_ops *ops;
	__le16 short_addr, pan_id;
	__le16 short_addr, pan_id;


	pr_debug("%s\n", __func__);
	pr_debug("%s\n", __func__);
@@ -273,11 +274,12 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
	if (!hdr)
	if (!hdr)
		goto out;
		goto out;


	phy = ieee802154_mlme_ops(dev)->get_phy(dev);
	ops = ieee802154_mlme_ops(dev);
	phy = ops->get_phy(dev);
	BUG_ON(!phy);
	BUG_ON(!phy);


	short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev);
	short_addr = ops->get_short_addr(dev);
	pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
	pan_id = ops->get_pan_id(dev);


	if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
	if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
	    nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
	    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_SHORT_ADDR, short_addr) ||
	    nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id))
	    nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id))
		goto nla_put_failure;
		goto nla_put_failure;

	if (ops->get_mac_params) {
		struct ieee802154_mac_params params;

		ops->get_mac_params(dev, &params);

		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);
	wpan_phy_put(phy);
	return genlmsg_end(msg, hdr);
	return genlmsg_end(msg, hdr);


@@ -599,3 +625,93 @@ int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)


	return skb->len;
	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, &params);

	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, &params);

	wpan_phy_put(phy);
	dev_put(dev);
	return rc;

out_phy:
	wpan_phy_put(phy);
out:
	dev_put(dev);
	return rc;
}
Loading