diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index f3fb18efe6441..e382db763e5d1 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -97,6 +97,9 @@ Devicetree superfamily. Therefore, any dts files for boards that use Series 2 SoCs will need to change their include from ``#include `` to ``#include ``. +* The :c:macro:`DT_ENUM_HAS_VALUE` and :c:macro:`DT_INST_ENUM_HAS_VALUE` macros are now + checking all values, when used on an array, not just the first one. + DAI === diff --git a/drivers/ethernet/phy/phy_mii.c b/drivers/ethernet/phy/phy_mii.c index 5a6522a9c5b13..2f7654a4f14a2 100644 --- a/drivers/ethernet/phy/phy_mii.c +++ b/drivers/ethernet/phy/phy_mii.c @@ -26,6 +26,7 @@ struct phy_mii_dev_config { bool no_reset; bool fixed; int fixed_speed; + enum phy_link_speed default_speeds; const struct device * const mdio; }; @@ -610,13 +611,8 @@ static int phy_mii_initialize_dynamic_link(const struct device *dev) k_work_init_delayable(&data->monitor_work, monitor_work_handler); k_work_init_delayable(&data->autoneg_work, autoneg_work_handler); - /* Advertise all speeds */ - phy_mii_cfg_link(dev, LINK_HALF_10BASE | - LINK_FULL_10BASE | - LINK_HALF_100BASE | - LINK_FULL_100BASE | - LINK_HALF_1000BASE | - LINK_FULL_1000BASE); + /* Advertise default speeds */ + phy_mii_cfg_link(dev, cfg->default_speeds); monitor_work_handler(&data->monitor_work.work); @@ -636,12 +632,24 @@ static DEVICE_API(ethphy, phy_mii_driver_api) = { #endif }; +#define PHY_MII_GENERATE_DEFAULT_SPEEDS(n) \ +((DT_INST_ENUM_HAS_VALUE(n, default_speeds, 10base_half_duplex) ? LINK_HALF_10BASE : 0) | \ +(DT_INST_ENUM_HAS_VALUE(n, default_speeds, 10base_full_duplex) ? LINK_FULL_10BASE : 0) | \ +(DT_INST_ENUM_HAS_VALUE(n, default_speeds, 100base_half_duplex) ? LINK_HALF_100BASE : 0) | \ +(DT_INST_ENUM_HAS_VALUE(n, default_speeds, 100base_full_duplex) ? LINK_FULL_100BASE : 0) | \ +(DT_INST_ENUM_HAS_VALUE(n, default_speeds, 1000base_half_duplex) ? LINK_HALF_1000BASE : 0) | \ +(DT_INST_ENUM_HAS_VALUE(n, default_speeds, 1000base_full_duplex) ? LINK_FULL_1000BASE : 0)) + #define PHY_MII_CONFIG(n) \ +BUILD_ASSERT(PHY_MII_GENERATE_DEFAULT_SPEEDS(n) != 0, \ + "At least one valid speed must be configured for this driver"); \ + \ static const struct phy_mii_dev_config phy_mii_dev_config_##n = { \ .phy_addr = DT_INST_REG_ADDR(n), \ .no_reset = DT_INST_PROP(n, no_reset), \ .fixed = IS_FIXED_LINK(n), \ .fixed_speed = DT_INST_ENUM_IDX_OR(n, fixed_link, 0), \ + .default_speeds = PHY_MII_GENERATE_DEFAULT_SPEEDS(n), \ .mdio = UTIL_AND(UTIL_NOT(IS_FIXED_LINK(n)), \ DEVICE_DT_GET(DT_INST_BUS(n))) \ }; diff --git a/dts/bindings/ethernet/phy/ethernet-phy.yaml b/dts/bindings/ethernet/phy/ethernet-phy.yaml index 2f9398e59e959..22704da0d40d6 100644 --- a/dts/bindings/ethernet/phy/ethernet-phy.yaml +++ b/dts/bindings/ethernet/phy/ethernet-phy.yaml @@ -26,3 +26,15 @@ properties: - "100BASE-T Full-Duplex" - "1000BASE-T Half-Duplex" - "1000BASE-T Full-Duplex" + default-speeds: + type: string-array + description: The selected speeds are used to configure the PHY during initialization + enum: + - "10BASE Half-Duplex" + - "10BASE Full-Duplex" + - "100BASE Half-Duplex" + - "100BASE Full-Duplex" + - "1000BASE Half-Duplex" + - "1000BASE Full-Duplex" + default: ["10BASE Half-Duplex", "10BASE Full-Duplex", "100BASE Half-Duplex", + "100BASE Full-Duplex", "1000BASE Half-Duplex", "1000BASE Full-Duplex"] diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 0860ae6b19b04..68dac5081f8b8 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -1045,14 +1045,14 @@ IS_ENABLED(DT_CAT8(node_id, _P_, prop, _IDX_, idx, _ENUM_VAL_, value, _EXISTS)) /** - * @brief Equivalent to DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, 0, value). + * @brief Does a node enumeration property have a given value? * @param node_id node identifier * @param prop lowercase-and-underscores property name * @param value lowercase-and-underscores enumeration value * @return 1 if the node property has the value @a value, 0 otherwise. */ #define DT_ENUM_HAS_VALUE(node_id, prop, value) \ - DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, 0, value) + IS_ENABLED(DT_CAT6(node_id, _P_, prop, _ENUM_VAL_, value, _EXISTS)) /** * @brief Get a string property's value as a token. diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index ee6a88dd1d106..93c4c3a635b24 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -686,6 +686,8 @@ def enum_macros(prop: edtlib.Property, macro: str): ret[f"{macro}_IDX_{i}_EXISTS"] = 1 # DT_N__P__IDX__ENUM_VAL__EXISTS 1 ret[f"{macro}_IDX_{i}_ENUM_VAL_{subval}_EXISTS"] = 1 + # DT_N__P__ENUM_VAL__EXISTS 1 + ret[f"{macro}_ENUM_VAL_{subval}_EXISTS"] = 1 return ret diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index d3cd23721d773..bb214ec6a7666 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -2193,6 +2193,12 @@ ZTEST(devicetree_api, test_enums) zassert_false(DT_ENUM_HAS_VALUE_BY_IDX(DT_NODELABEL(test_enum_string_array), val, 2, bar)); zassert_false(DT_ENUM_HAS_VALUE_BY_IDX(DT_NODELABEL(test_enum_string_array), val, 2, zoo)); + /* DT_ENUM_HAS_VALUE on string-array enum */ + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_string_array), val, foo)); + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_string_array), val, zoo)); + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_string_array), val, foo)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_string_array), val, baz)); + /* DT_ENUM_IDX_BY_IDX and DT_ENUM_HAS_VALUE_BY_IDX on int-array enum */ zassert_equal(DT_ENUM_IDX_BY_IDX(DT_NODELABEL(test_enum_int_array), val, 0), 3); zassert_equal(DT_ENUM_IDX_BY_IDX(DT_NODELABEL(test_enum_int_array), val, 1), 4); @@ -2210,6 +2216,16 @@ ZTEST(devicetree_api, test_enums) zassert_true(DT_ENUM_HAS_VALUE_BY_IDX(DT_NODELABEL(test_enum_int_array), val, 3, 0)); zassert_false(DT_ENUM_HAS_VALUE_BY_IDX(DT_NODELABEL(test_enum_int_array), val, 3, 2)); zassert_false(DT_ENUM_HAS_VALUE_BY_IDX(DT_NODELABEL(test_enum_int_array), val, 3, 1)); + + /* DT_ENUM_HAS_VALUE on int-array enum */ + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 0)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 1)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 2)); + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 3)); + zassert_true(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 4)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 5)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 6)); + zassert_false(DT_ENUM_HAS_VALUE(DT_NODELABEL(test_enum_int_array), val, 7)); } #undef TO_MY_ENUM #undef TO_MY_ENUM_2