Skip to content

Commit

Permalink
mac802154: make csma/cca parameters per-wpan
Browse files Browse the repository at this point in the history
Commit 9b2777d (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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Phoebe Buckheister authored and davem330 committed Apr 1, 2014
1 parent 336908f commit e462ded
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 236 deletions.
2 changes: 1 addition & 1 deletion include/linux/nl802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ enum {
IEEE802154_ADD_IFACE,
IEEE802154_DEL_IFACE,

IEEE802154_SET_PHYPARAMS,
IEEE802154_SET_MACPARAMS,

__IEEE802154_CMD_MAX,
};
Expand Down
17 changes: 17 additions & 0 deletions include/net/ieee802154_netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,18 @@ static inline int mac_cb_type(struct sk_buff *skb)
#define IEEE802154_MAC_SCAN_PASSIVE 2
#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;
/*
* This should be located at net_device->ml_priv
Expand All @@ -255,6 +267,11 @@ struct ieee802154_mlme_ops {
int (*scan_req)(struct net_device *dev,
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. */

struct wpan_phy *(*get_phy)(const struct net_device *dev);
Expand Down
2 changes: 1 addition & 1 deletion net/ieee802154/ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_add_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 {
IEEE802154_COORD_MCGRP,
Expand All @@ -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_list_iface(struct sk_buff *skb, struct genl_info *info);
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
2 changes: 1 addition & 1 deletion net/ieee802154/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ static const struct genl_ops ieee8021154_ops[] = {
ieee802154_dump_phy),
IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
IEEE802154_OP(IEEE802154_SET_PHYPARAMS, ieee802154_set_phyparams),
/* see nl-mac.c */
IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
Expand All @@ -124,6 +123,7 @@ static const struct genl_ops ieee8021154_ops[] = {
IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
ieee802154_dump_iface),
IEEE802154_OP(IEEE802154_SET_MACPARAMS, ieee802154_set_macparams),
};

static const struct genl_multicast_group ieee802154_mcgrps[] = {
Expand Down
122 changes: 119 additions & 3 deletions net/ieee802154/nl-mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__);
Expand All @@ -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)) ||
Expand All @@ -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, &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);
return genlmsg_end(msg, hdr);

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

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

0 comments on commit e462ded

Please sign in to comment.