nl802154: add support for dump phy capabilities
This patch add support to nl802154 to dump all phy capabilities which is inside the wpan_phy_supported struct. Also we introduce a new method to dumping supported channels. The new method will offer a easier interface and has lesser netlink traffic. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
392f4e67ad
commit
0e66545701
|
@ -100,6 +100,8 @@ enum nl802154_attrs {
|
||||||
|
|
||||||
NL802154_ATTR_EXTENDED_ADDR,
|
NL802154_ATTR_EXTENDED_ADDR,
|
||||||
|
|
||||||
|
NL802154_ATTR_WPAN_PHY_CAPS,
|
||||||
|
|
||||||
/* add attributes here, update the policy in nl802154.c */
|
/* add attributes here, update the policy in nl802154.c */
|
||||||
|
|
||||||
__NL802154_ATTR_AFTER_LAST,
|
__NL802154_ATTR_AFTER_LAST,
|
||||||
|
@ -119,6 +121,61 @@ enum nl802154_iftype {
|
||||||
NL802154_IFTYPE_MAX = NUM_NL802154_IFTYPES - 1
|
NL802154_IFTYPE_MAX = NUM_NL802154_IFTYPES - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum nl802154_wpan_phy_capability_attr - wpan phy capability attributes
|
||||||
|
*
|
||||||
|
* @__NL802154_CAP_ATTR_INVALID: attribute number 0 is reserved
|
||||||
|
* @NL802154_CAP_ATTR_CHANNELS: a nested attribute for nl802154_channel_attr
|
||||||
|
* @NL802154_CAP_ATTR_TX_POWERS: a nested attribute for
|
||||||
|
* nl802154_wpan_phy_tx_power
|
||||||
|
* @NL802154_CAP_ATTR_MIN_CCA_ED_LEVEL: minimum value for cca_ed_level
|
||||||
|
* @NL802154_CAP_ATTR_MAX_CCA_ED_LEVEL: maxmimum value for cca_ed_level
|
||||||
|
* @NL802154_CAP_ATTR_CCA_MODES: nl802154_cca_modes flags
|
||||||
|
* @NL802154_CAP_ATTR_CCA_OPTS: nl802154_cca_opts flags
|
||||||
|
* @NL802154_CAP_ATTR_MIN_MINBE: minimum of minbe value
|
||||||
|
* @NL802154_CAP_ATTR_MAX_MINBE: maximum of minbe value
|
||||||
|
* @NL802154_CAP_ATTR_MIN_MAXBE: minimum of maxbe value
|
||||||
|
* @NL802154_CAP_ATTR_MAX_MINBE: maximum of maxbe value
|
||||||
|
* @NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS: minimum of csma backoff value
|
||||||
|
* @NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS: maximum of csma backoffs value
|
||||||
|
* @NL802154_CAP_ATTR_MIN_FRAME_RETRIES: minimum of frame retries value
|
||||||
|
* @NL802154_CAP_ATTR_MAX_FRAME_RETRIES: maximum of frame retries value
|
||||||
|
* @NL802154_CAP_ATTR_IFTYPES: nl802154_iftype flags
|
||||||
|
* @NL802154_CAP_ATTR_LBT: nl802154_supported_bool_states flags
|
||||||
|
* @NL802154_CAP_ATTR_MAX: highest cap attribute currently defined
|
||||||
|
* @__NL802154_CAP_ATTR_AFTER_LAST: internal use
|
||||||
|
*/
|
||||||
|
enum nl802154_wpan_phy_capability_attr {
|
||||||
|
__NL802154_CAP_ATTR_INVALID,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_IFTYPES,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_CHANNELS,
|
||||||
|
NL802154_CAP_ATTR_TX_POWERS,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_CCA_ED_LEVELS,
|
||||||
|
NL802154_CAP_ATTR_CCA_MODES,
|
||||||
|
NL802154_CAP_ATTR_CCA_OPTS,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_MIN_MINBE,
|
||||||
|
NL802154_CAP_ATTR_MAX_MINBE,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_MIN_MAXBE,
|
||||||
|
NL802154_CAP_ATTR_MAX_MAXBE,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
|
||||||
|
NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
|
||||||
|
NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
|
||||||
|
|
||||||
|
NL802154_CAP_ATTR_LBT,
|
||||||
|
|
||||||
|
/* keep last */
|
||||||
|
__NL802154_CAP_ATTR_AFTER_LAST,
|
||||||
|
NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum nl802154_cca_modes - cca modes
|
* enum nl802154_cca_modes - cca modes
|
||||||
*
|
*
|
||||||
|
|
|
@ -225,6 +225,8 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
|
||||||
[NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
|
[NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
|
||||||
|
|
||||||
[NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
|
[NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
|
||||||
|
|
||||||
|
[NL802154_ATTR_WPAN_PHY_CAPS] = { .type = NLA_NESTED },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* message building helper */
|
/* message building helper */
|
||||||
|
@ -235,6 +237,28 @@ static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
|
||||||
return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd);
|
return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask)
|
||||||
|
{
|
||||||
|
struct nlattr *nl_flags = nla_nest_start(msg, attr);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!nl_flags)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (mask) {
|
||||||
|
if ((mask & 1) && nla_put_flag(msg, i))
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
mask >>= 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(msg, nl_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
|
nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
|
||||||
struct sk_buff *msg)
|
struct sk_buff *msg)
|
||||||
|
@ -256,6 +280,92 @@ nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nl802154_put_capabilities(struct sk_buff *msg,
|
||||||
|
struct cfg802154_registered_device *rdev)
|
||||||
|
{
|
||||||
|
const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported;
|
||||||
|
struct nlattr *nl_caps, *nl_channels;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nl_caps = nla_nest_start(msg, NL802154_ATTR_WPAN_PHY_CAPS);
|
||||||
|
if (!nl_caps)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
nl_channels = nla_nest_start(msg, NL802154_CAP_ATTR_CHANNELS);
|
||||||
|
if (!nl_channels)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
for (i = 0; i <= IEEE802154_MAX_PAGE; i++) {
|
||||||
|
if (caps->channels[i]) {
|
||||||
|
if (nl802154_put_flags(msg, i, caps->channels[i]))
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(msg, nl_channels);
|
||||||
|
|
||||||
|
if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
|
||||||
|
struct nlattr *nl_ed_lvls;
|
||||||
|
|
||||||
|
nl_ed_lvls = nla_nest_start(msg,
|
||||||
|
NL802154_CAP_ATTR_CCA_ED_LEVELS);
|
||||||
|
if (!nl_ed_lvls)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
for (i = 0; i < caps->cca_ed_levels_size; i++) {
|
||||||
|
if (nla_put_s32(msg, i, caps->cca_ed_levels[i]))
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(msg, nl_ed_lvls);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
|
||||||
|
struct nlattr *nl_tx_pwrs;
|
||||||
|
|
||||||
|
nl_tx_pwrs = nla_nest_start(msg, NL802154_CAP_ATTR_TX_POWERS);
|
||||||
|
if (!nl_tx_pwrs)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
for (i = 0; i < caps->tx_powers_size; i++) {
|
||||||
|
if (nla_put_s32(msg, i, caps->tx_powers[i]))
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(msg, nl_tx_pwrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
|
||||||
|
if (nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_MODES,
|
||||||
|
caps->cca_modes) ||
|
||||||
|
nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_OPTS,
|
||||||
|
caps->cca_opts))
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MINBE, caps->min_minbe) ||
|
||||||
|
nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MINBE, caps->max_minbe) ||
|
||||||
|
nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MAXBE, caps->min_maxbe) ||
|
||||||
|
nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MAXBE, caps->max_maxbe) ||
|
||||||
|
nla_put_u8(msg, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
|
||||||
|
caps->min_csma_backoffs) ||
|
||||||
|
nla_put_u8(msg, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
|
||||||
|
caps->max_csma_backoffs) ||
|
||||||
|
nla_put_s8(msg, NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
|
||||||
|
caps->min_frame_retries) ||
|
||||||
|
nla_put_s8(msg, NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
|
||||||
|
caps->max_frame_retries) ||
|
||||||
|
nl802154_put_flags(msg, NL802154_CAP_ATTR_IFTYPES,
|
||||||
|
caps->iftypes) ||
|
||||||
|
nla_put_u32(msg, NL802154_CAP_ATTR_LBT, caps->lbt))
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
nla_nest_end(msg, nl_caps);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
|
static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
|
||||||
enum nl802154_commands cmd,
|
enum nl802154_commands cmd,
|
||||||
struct sk_buff *msg, u32 portid, u32 seq,
|
struct sk_buff *msg, u32 portid, u32 seq,
|
||||||
|
@ -286,7 +396,9 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
|
||||||
rdev->wpan_phy.current_channel))
|
rdev->wpan_phy.current_channel))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
/* supported channels array */
|
/* TODO remove this behaviour, we still keep support it for a while
|
||||||
|
* so users can change the behaviour to the new one.
|
||||||
|
*/
|
||||||
if (nl802154_send_wpan_phy_channels(rdev, msg))
|
if (nl802154_send_wpan_phy_channels(rdev, msg))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
@ -309,6 +421,9 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nl802154_put_capabilities(msg, rdev))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
genlmsg_end(msg, hdr);
|
genlmsg_end(msg, hdr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue