diff --git a/sys/include/net/ieee802154/submac.h b/sys/include/net/ieee802154/submac.h index 5548ce9f8c..9ec703b231 100644 --- a/sys/include/net/ieee802154/submac.h +++ b/sys/include/net/ieee802154/submac.h @@ -120,6 +120,7 @@ struct ieee802154_submac { uint8_t csma_retries; /**< maximum number of CSMA-CA retries */ int8_t tx_pow; /**< Transmission power (in dBm) */ ieee802154_submac_state_t state; /**< State of the SubMAC */ + ieee802154_phy_mode_t phy_mode; /**< IEEE 802.15.4 PHY mode */ }; /** @@ -225,6 +226,19 @@ static inline int ieee802154_set_panid(ieee802154_submac_t *submac, return res; } +/** + * @brief Get IEEE 802.15.4 PHY mode + * + * @param[in] submac pointer to the SubMAC descriptor + * + * @return PHY mode. + */ +static inline ieee802154_phy_mode_t ieee802154_get_phy_mode( + ieee802154_submac_t *submac) +{ + return submac->phy_mode; +} + /** * @brief Set IEEE 802.15.4 PHY configuration (channel, TX power) * diff --git a/sys/net/link_layer/ieee802154/submac.c b/sys/net/link_layer/ieee802154/submac.c index 352e3da991..f9ea58a933 100644 --- a/sys/net/link_layer/ieee802154/submac.c +++ b/sys/net/link_layer/ieee802154/submac.c @@ -337,6 +337,29 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t * submac->channel_page = CONFIG_IEEE802154_DEFAULT_SUBGHZ_PAGE; } + /* Get supported PHY modes */ + int supported_phy_modes = ieee802154_radio_get_phy_modes(dev); + assert(supported_phy_modes != 0); + + uint32_t default_phy_cap = ieee802154_phy_mode_to_cap(CONFIG_IEEE802154_DEFAULT_PHY_MODE); + + /* Check if configuration provides valid PHY */ + if (CONFIG_IEEE802154_DEFAULT_PHY_MODE != IEEE802154_PHY_DISABLED && + (supported_phy_modes & default_phy_cap)) { + /* Check if default PHY is supported */ + submac->phy_mode = CONFIG_IEEE802154_DEFAULT_PHY_MODE; + } + else { + /* Get first set bit, and use it as the default, + * + * by this order, the priority is defined on the ieee802154_rf_caps_t + * definition, first IEEE 802.15.4-2006 PHY modes, then + * IEEE 802.15.4g-2012 PHY modes. */ + unsigned bit = bitarithm_lsb(supported_phy_modes); + + submac->phy_mode = ieee802154_cap_to_phy_mode(1 << bit); + } + /* If the radio is still not in TRX_OFF state, spin */ while (ieee802154_radio_confirm_on(dev) == -EAGAIN) {} @@ -347,9 +370,10 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t * ieee802154_radio_set_hw_addr_filter(dev, &submac->short_addr, &submac->ext_addr, &submac->panid); - /* Configure PHY settings (channel, TX power) */ + /* Configure PHY settings (mode, channel, TX power) */ ieee802154_phy_conf_t conf = - { .channel = CONFIG_IEEE802154_DEFAULT_CHANNEL, + { .phy_mode = submac->phy_mode, + .channel = CONFIG_IEEE802154_DEFAULT_CHANNEL, .page = CONFIG_IEEE802154_DEFAULT_CHANNEL, .pow = CONFIG_IEEE802154_DEFAULT_TXPOWER }; @@ -367,7 +391,10 @@ int ieee802154_set_phy_conf(ieee802154_submac_t *submac, uint16_t channel_num, { ieee802154_dev_t *dev = submac->dev; const ieee802154_phy_conf_t conf = - { .channel = channel_num, .page = channel_page, .pow = tx_pow }; + { .phy_mode = submac->phy_mode, + .channel = channel_num, + .page = channel_page, + .pow = tx_pow }; if (submac->state == IEEE802154_STATE_OFF) { return -ENETDOWN;