Commit fea3318d authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann

ieee802154: add several phy supported handling

This patch adds support for phy supported handling for all other already
existing handling 802.15.4 functionality. We assume now a fully 802.15.4
complaint transceiver at phy allocation. If a transceiver can support
802.15.4 default values only, then the values should be overwirtten by
values the transceiver supports. If the transceiver doesn't set the
according hardware flags, we assume the 802.15.4 defaults now which
cannot be changed.
Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Suggested-by: default avatarPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 72f655e4
...@@ -61,8 +61,32 @@ struct cfg802154_ops { ...@@ -61,8 +61,32 @@ struct cfg802154_ops {
struct wpan_dev *wpan_dev, bool mode); struct wpan_dev *wpan_dev, bool mode);
}; };
static inline bool
wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
{
switch (st) {
case NL802154_SUPPORTED_BOOL_TRUE:
return b;
case NL802154_SUPPORTED_BOOL_FALSE:
return !b;
case NL802154_SUPPORTED_BOOL_BOTH:
return true;
default:
WARN_ON(1);
}
return false;
}
struct wpan_phy_supported { struct wpan_phy_supported {
u32 channels[IEEE802154_MAX_PAGE + 1]; u32 channels[IEEE802154_MAX_PAGE + 1],
cca_modes, cca_opts;
enum nl802154_supported_bool_states lbt;
u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
min_csma_backoffs, max_csma_backoffs;
s8 min_frame_retries, max_frame_retries;
size_t tx_powers_size, cca_ed_levels_size;
const s32 *tx_powers, *cca_ed_levels;
}; };
struct wpan_phy_cca { struct wpan_phy_cca {
......
...@@ -162,4 +162,26 @@ enum nl802154_cca_opts { ...@@ -162,4 +162,26 @@ enum nl802154_cca_opts {
NL802154_CCA_OPT_ATTR_MAX = __NL802154_CCA_OPT_ATTR_AFTER_LAST - 1 NL802154_CCA_OPT_ATTR_MAX = __NL802154_CCA_OPT_ATTR_AFTER_LAST - 1
}; };
/**
* enum nl802154_supported_bool_states - bool states for bool capability entry
*
* @NL802154_SUPPORTED_BOOL_FALSE: indicates to set false
* @NL802154_SUPPORTED_BOOL_TRUE: indicates to set true
* @__NL802154_SUPPORTED_BOOL_INVALD: reserved
* @NL802154_SUPPORTED_BOOL_BOTH: indicates to set true and false
* @__NL802154_SUPPORTED_BOOL_AFTER_LAST: Internal
* @NL802154_SUPPORTED_BOOL_MAX: highest value for bool states
*/
enum nl802154_supported_bool_states {
NL802154_SUPPORTED_BOOL_FALSE,
NL802154_SUPPORTED_BOOL_TRUE,
/* to handle them in a mask */
__NL802154_SUPPORTED_BOOL_INVALD,
NL802154_SUPPORTED_BOOL_BOTH,
/* keep last */
__NL802154_SUPPORTED_BOOL_AFTER_LAST,
NL802154_SUPPORTED_BOOL_MAX = __NL802154_SUPPORTED_BOOL_AFTER_LAST - 1
};
#endif /* __NL802154_H */ #endif /* __NL802154_H */
...@@ -642,7 +642,9 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info) ...@@ -642,7 +642,9 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]); cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]);
/* checking 802.15.4 constraints */ /* checking 802.15.4 constraints */
if (cca.mode < NL802154_CCA_ENERGY || cca.mode > NL802154_CCA_ATTR_MAX) if (cca.mode < NL802154_CCA_ENERGY ||
cca.mode > NL802154_CCA_ATTR_MAX ||
!(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode)))
return -EINVAL; return -EINVAL;
if (cca.mode == NL802154_CCA_ENERGY_CARRIER) { if (cca.mode == NL802154_CCA_ENERGY_CARRIER) {
...@@ -650,7 +652,8 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info) ...@@ -650,7 +652,8 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]); cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]);
if (cca.opt > NL802154_CCA_OPT_ATTR_MAX) if (cca.opt > NL802154_CCA_OPT_ATTR_MAX ||
!(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt)))
return -EINVAL; return -EINVAL;
} }
...@@ -744,7 +747,11 @@ nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info) ...@@ -744,7 +747,11 @@ nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]); max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
/* check 802.15.4 constraints */ /* check 802.15.4 constraints */
if (max_be < 3 || max_be > 8 || min_be > max_be) if (min_be < rdev->wpan_phy.supported.min_minbe ||
min_be > rdev->wpan_phy.supported.max_minbe ||
max_be < rdev->wpan_phy.supported.min_maxbe ||
max_be > rdev->wpan_phy.supported.max_maxbe ||
min_be > max_be)
return -EINVAL; return -EINVAL;
return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be); return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
...@@ -769,7 +776,8 @@ nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info) ...@@ -769,7 +776,8 @@ nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]); info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
/* check 802.15.4 constraints */ /* check 802.15.4 constraints */
if (max_csma_backoffs > 5) if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs ||
max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs)
return -EINVAL; return -EINVAL;
return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs); return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
...@@ -793,7 +801,8 @@ nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info) ...@@ -793,7 +801,8 @@ nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]); info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
/* check 802.15.4 constraints */ /* check 802.15.4 constraints */
if (max_frame_retries < -1 || max_frame_retries > 7) if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries ||
max_frame_retries > rdev->wpan_phy.supported.max_frame_retries)
return -EINVAL; return -EINVAL;
return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries); return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
...@@ -813,6 +822,9 @@ static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info) ...@@ -813,6 +822,9 @@ static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]); mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
return -EINVAL;
return rdev_set_lbt_mode(rdev, wpan_dev, mode); return rdev_set_lbt_mode(rdev, wpan_dev, mode);
} }
......
...@@ -107,6 +107,15 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) ...@@ -107,6 +107,15 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
skb_queue_head_init(&local->skb_queue); skb_queue_head_init(&local->skb_queue);
/* init supported flags with 802.15.4 default ranges */
phy->supported.max_minbe = 8;
phy->supported.min_maxbe = 3;
phy->supported.max_maxbe = 8;
phy->supported.min_frame_retries = -1;
phy->supported.max_frame_retries = 7;
phy->supported.max_csma_backoffs = 5;
phy->supported.lbt = NL802154_SUPPORTED_BOOL_FALSE;
return &local->hw; return &local->hw;
} }
EXPORT_SYMBOL(ieee802154_alloc_hw); EXPORT_SYMBOL(ieee802154_alloc_hw);
...@@ -155,6 +164,23 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) ...@@ -155,6 +164,23 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
ieee802154_setup_wpan_phy_pib(local->phy); ieee802154_setup_wpan_phy_pib(local->phy);
if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) {
local->phy->supported.min_csma_backoffs = 4;
local->phy->supported.max_csma_backoffs = 4;
local->phy->supported.min_maxbe = 5;
local->phy->supported.max_maxbe = 5;
local->phy->supported.min_minbe = 3;
local->phy->supported.max_minbe = 3;
}
if (!(hw->flags & IEEE802154_HW_FRAME_RETRIES)) {
/* TODO should be 3, but our default value is -1 which means
* no ARET handling.
*/
local->phy->supported.min_frame_retries = -1;
local->phy->supported.max_frame_retries = -1;
}
rc = wpan_phy_register(local->phy); rc = wpan_phy_register(local->phy);
if (rc < 0) if (rc < 0)
goto out_wq; goto out_wq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment