mac802154: make csma/cca parameters per-wpan

Commit 9b2777d608 (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>
This commit is contained in:
Phoebe Buckheister
2014-03-31 21:37:46 +02:00
committed by David S. Miller
parent 336908f6d7
commit e462ded699
11 changed files with 252 additions and 236 deletions
+1 -1
View File
@@ -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,
@@ -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
+1 -1
View File
@@ -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),
@@ -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[] = {
+119 -3
View File
@@ -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, &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);
@@ -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, &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;
}
+1 -199
View File
@@ -55,15 +55,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
mutex_lock(&phy->pib_lock);
if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) ||
nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) ||
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_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))
nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel))
goto nla_put_failure;
for (i = 0; i < 32; i++) {
if (phy->channels_supported[i])
@@ -362,193 +354,3 @@ out_dev:
return rc;
}
static int phy_set_txpower(struct wpan_phy *phy, struct genl_info *info)
{
int txpower = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
int rc;
rc = phy->set_txpower(phy, txpower);
if (rc < 0)
return rc;
phy->transmit_power = txpower;
return 0;
}
static int phy_set_lbt(struct wpan_phy *phy, struct genl_info *info)
{
u8 on = !!nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]);
int rc;
rc = phy->set_lbt(phy, on);
if (rc < 0)
return rc;
phy->lbt = on;
return 0;
}
static int phy_set_cca_mode(struct wpan_phy *phy, struct genl_info *info)
{
u8 mode = nla_get_u8(info->attrs[IEEE802154_ATTR_CCA_MODE]);
int rc;
if (mode > 3)
return -EINVAL;
rc = phy->set_cca_mode(phy, mode);
if (rc < 0)
return rc;
phy->cca_mode = mode;
return 0;
}
static int phy_set_cca_ed_level(struct wpan_phy *phy, struct genl_info *info)
{
s32 level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]);
int rc;
rc = phy->set_cca_ed_level(phy, level);
if (rc < 0)
return rc;
phy->cca_ed_level = level;
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 < 3 || max_be > 8 || min_be > max_be)
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;
if (retries < -1 || retries > 7)
return -EINVAL;
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;
const char *name;
int rc = -ENOTSUPP;
pr_debug("%s\n", __func__);
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_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]);
if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
return -EINVAL; /* phy name should be null-terminated */
phy = wpan_phy_find(name);
if (!phy)
return -ENODEV;
if ((!phy->set_txpower && info->attrs[IEEE802154_ATTR_TXPOWER]) ||
(!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]))
goto out;
mutex_lock(&phy->pib_lock);
if (info->attrs[IEEE802154_ATTR_TXPOWER]) {
rc = phy_set_txpower(phy, info);
if (rc < 0)
goto error;
}
if (info->attrs[IEEE802154_ATTR_LBT_ENABLED]) {
rc = phy_set_lbt(phy, info);
if (rc < 0)
goto error;
}
if (info->attrs[IEEE802154_ATTR_CCA_MODE]) {
rc = phy_set_cca_mode(phy, info);
if (rc < 0)
goto error;
}
if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) {
rc = phy_set_cca_ed_level(phy, info);
if (rc < 0)
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);
return 0;
error:
mutex_unlock(&phy->pib_lock);
out:
wpan_phy_put(phy);
return rc;
}
-6
View File
@@ -169,12 +169,6 @@ 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: