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 <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7dcbd22a97
commit
4244db1b0b
@ -74,6 +74,11 @@ enum {
|
|||||||
IEEE802154_ATTR_LBT_ENABLED,
|
IEEE802154_ATTR_LBT_ENABLED,
|
||||||
IEEE802154_ATTR_CCA_MODE,
|
IEEE802154_ATTR_CCA_MODE,
|
||||||
IEEE802154_ATTR_CCA_ED_LEVEL,
|
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,
|
__IEEE802154_ATTR_MAX,
|
||||||
};
|
};
|
||||||
|
@ -131,6 +131,14 @@ struct ieee802154_dev {
|
|||||||
* Sets the CCA energy detection threshold in dBm. Called with pib_lock
|
* Sets the CCA energy detection threshold in dBm. Called with pib_lock
|
||||||
* held.
|
* held.
|
||||||
* Returns either zero, or negative errno.
|
* 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 ieee802154_ops {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
@ -152,6 +160,10 @@ struct ieee802154_ops {
|
|||||||
int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode);
|
int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode);
|
||||||
int (*set_cca_ed_level)(struct ieee802154_dev *dev,
|
int (*set_cca_ed_level)(struct ieee802154_dev *dev,
|
||||||
s32 level);
|
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 */
|
/* Basic interface to register ieee802154 device */
|
||||||
|
@ -46,6 +46,10 @@ struct wpan_phy {
|
|||||||
u32 channels_supported[32];
|
u32 channels_supported[32];
|
||||||
s8 transmit_power;
|
s8 transmit_power;
|
||||||
u8 cca_mode;
|
u8 cca_mode;
|
||||||
|
u8 min_be;
|
||||||
|
u8 max_be;
|
||||||
|
u8 csma_retries;
|
||||||
|
s8 frame_retries;
|
||||||
|
|
||||||
bool lbt;
|
bool lbt;
|
||||||
s32 cca_ed_level;
|
s32 cca_ed_level;
|
||||||
@ -61,6 +65,9 @@ struct wpan_phy {
|
|||||||
int (*set_lbt)(struct wpan_phy *phy, bool on);
|
int (*set_lbt)(struct wpan_phy *phy, bool on);
|
||||||
int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode);
|
int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode);
|
||||||
int (*set_cca_ed_level)(struct wpan_phy *phy, int level);
|
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)));
|
char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
|
||||||
};
|
};
|
||||||
|
@ -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_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) ||
|
||||||
nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) ||
|
nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) ||
|
||||||
nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, phy->cca_mode) ||
|
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;
|
goto nla_put_failure;
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
if (phy->channels_supported[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;
|
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)
|
int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info)
|
||||||
{
|
{
|
||||||
struct wpan_phy *phy;
|
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] &&
|
if (!info->attrs[IEEE802154_ATTR_PHY_NAME] &&
|
||||||
!info->attrs[IEEE802154_ATTR_LBT_ENABLED] &&
|
!info->attrs[IEEE802154_ATTR_LBT_ENABLED] &&
|
||||||
!info->attrs[IEEE802154_ATTR_CCA_MODE] &&
|
!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;
|
return -EINVAL;
|
||||||
|
|
||||||
name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
|
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;
|
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);
|
mutex_unlock(&phy->pib_lock);
|
||||||
|
|
||||||
wpan_phy_put(phy);
|
wpan_phy_put(phy);
|
||||||
|
@ -57,5 +57,10 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
|
|||||||
[IEEE802154_ATTR_LBT_ENABLED] = { .type = NLA_U8, },
|
[IEEE802154_ATTR_LBT_ENABLED] = { .type = NLA_U8, },
|
||||||
[IEEE802154_ATTR_CCA_MODE] = { .type = NLA_U8, },
|
[IEEE802154_ATTR_CCA_MODE] = { .type = NLA_U8, },
|
||||||
[IEEE802154_ATTR_CCA_ED_LEVEL] = { .type = NLA_S32, },
|
[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, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,6 +169,12 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
|
|||||||
phy->current_channel = -1; /* not initialised */
|
phy->current_channel = -1; /* not initialised */
|
||||||
phy->current_page = 0; /* for compatibility */
|
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;
|
return phy;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -205,6 +205,27 @@ static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level)
|
|||||||
return priv->ops->set_cca_ed_level(&priv->hw, level);
|
return priv->ops->set_cca_ed_level(&priv->hw, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be,
|
||||||
|
u8 max_be, u8 retries)
|
||||||
|
{
|
||||||
|
struct mac802154_priv *priv = wpan_phy_priv(phy);
|
||||||
|
|
||||||
|
if (!priv->ops->set_csma_params)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries)
|
||||||
|
{
|
||||||
|
struct mac802154_priv *priv = wpan_phy_priv(phy);
|
||||||
|
|
||||||
|
if (!priv->ops->set_frame_retries)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
return priv->ops->set_frame_retries(&priv->hw, retries);
|
||||||
|
}
|
||||||
|
|
||||||
struct ieee802154_dev *
|
struct ieee802154_dev *
|
||||||
ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops)
|
ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops)
|
||||||
{
|
{
|
||||||
@ -286,6 +307,8 @@ int ieee802154_register_device(struct ieee802154_dev *dev)
|
|||||||
priv->phy->set_lbt = mac802154_set_lbt;
|
priv->phy->set_lbt = mac802154_set_lbt;
|
||||||
priv->phy->set_cca_mode = mac802154_set_cca_mode;
|
priv->phy->set_cca_mode = mac802154_set_cca_mode;
|
||||||
priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level;
|
priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level;
|
||||||
|
priv->phy->set_csma_params = mac802154_set_csma_params;
|
||||||
|
priv->phy->set_frame_retries = mac802154_set_frame_retries;
|
||||||
|
|
||||||
rc = wpan_phy_register(priv->phy);
|
rc = wpan_phy_register(priv->phy);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user