diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 14a1375a2e0..ba602aadd1c 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -29,7 +29,6 @@ &emdio { pinctrl-0 = <&emdio_default>; pinctrl-names = "default"; - protocol = "clause 22"; status = "okay"; phy0: ethernet-phy { diff --git a/drivers/ethernet/phy/phy_adin2111.c b/drivers/ethernet/phy/phy_adin2111.c index 86f92f6e710..eb90eddd013 100644 --- a/drivers/ethernet/phy/phy_adin2111.c +++ b/drivers/ethernet/phy/phy_adin2111.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +18,8 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #include #include #include +#include #include -#include /* PHYs out of reset check retry delay */ #define ADIN2111_PHY_AWAIT_DELAY_POLL_US 15U @@ -37,36 +38,10 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #define ADIN2111_PHY_ID 0x0283BCA1U #define ADIN1110_PHY_ID 0x0283BC91U -/* 10BASE-T1L PMA Status Register */ -#define ADIN2111_PHY_PMA_STATUS 0x000108F7U -/* Indicates PHY support of 10BASE-T1L high voltage (2.4V) tx level op mode */ -#define ADIN2111_PHY_PMA_STATUS_B10L_TX_LVL_HI_ABLE BIT(12) - -/* BASE-T1 Autonegotiation Control Register */ -#define ADIN2111_PHY_AN_CONTROL 0x00070200U -/* Autonegotiation Enable */ -#define ADIN2111_PHY_AN_CONTROL_AN_EN BIT(12) -/* Autonegotiation Restart */ -#define ADIN2111_PHY_AN_CONTROL_AN_RESTART BIT(9) - -/* BASE-T1 Autonegotiation Status Register */ -#define ADIN2111_PHY_AN_STATUS 0x00070201U -/* Autonegotiation Complete */ -#define ADIN2111_PHY_AN_STATUS_AN_COMPLETE BIT(5) -/* Link Status */ -#define ADIN2111_PHY_AN_STATUS_AN_LINK_STATUS BIT(2) - -/* 10BASE-T1 Autonegotiation Advertisement Register */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H 0x00070204U -/* Advertise PHY capability of 2.4V tx level op mode */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL BIT(13) -/* Advertise PHY request of 2.4V tx level op mode */ -#define ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ BIT(12) - /* System Interrupt Mask Register */ -#define ADIN2111_PHY_CRSM_IRQ_MASK 0x001E0020U +#define ADIN2111_PHY_CRSM_IRQ_MASK 0x0020U /* System Interrupt Status Register */ -#define ADIN2111_PHY_CRSM_IRQ_STATUS 0x001E0010U +#define ADIN2111_PHY_CRSM_IRQ_STATUS 0x0010U /** * Mask of reserved interrupts that indicates a fatal error in the system. * @@ -82,21 +57,21 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL); #define ADIN2111_PHY_CRSM_IRQ_STATUS_FATAL_ERR 0x2BFFU /* PHY Subsystem Interrupt Mask Register */ -#define ADIN2111_PHY_SUBSYS_IRQ_MASK 0x001F0021U +#define ADIN2111_PHY_SUBSYS_IRQ_MASK 0x0021U /* PHY Subsystem Interrupt Status Register */ -#define ADIN2111_PHY_SUBSYS_IRQ_STATUS 0x001F0011U +#define ADIN2111_PHY_SUBSYS_IRQ_STATUS 0x0011U /* Link Status Change */ #define ADIN2111_PHY_SUBSYS_IRQ_STATUS_LINK_STAT_CHNG_LH BIT(1) /* Software Power-down Control Register */ -#define ADIN2111_PHY_CRSM_SFT_PD_CNTRL 0x001E8812U +#define ADIN2111_PHY_CRSM_SFT_PD_CNTRL 0x8812U /* System Status Register */ -#define ADIN2111_PHY_CRSM_STAT 0x001E8818U +#define ADIN2111_PHY_CRSM_STAT 0x8818U /* Software Power-down Status */ #define ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY BIT(1) /* LED Control Register */ -#define ADIN2111_PHY_LED_CNTRL 0x001E8C82U +#define ADIN2111_PHY_LED_CNTRL 0x8C82U /* LED 1 Enable */ #define ADIN2111_PHY_LED_CNTRL_LED1_EN BIT(15) /* LED 0 Enable */ @@ -131,22 +106,20 @@ static inline int phy_adin2111_c22_write(const struct device *dev, uint16_t reg, return mdio_write(cfg->mdio, cfg->phy_addr, reg, val); } -static inline int phy_adin2111_c45_write(const struct device *dev, uint32_t reg, - uint16_t val) +static inline int phy_adin2111_c45_write(const struct device *dev, uint16_t devad, + uint16_t reg, uint16_t val) { const struct phy_adin2111_config *cfg = dev->config; - return adin2111_mdio_c45_write(cfg->mdio, cfg->phy_addr, ((reg >> 16U) & 0x1FU), - (reg & UINT16_MAX), val); + return mdio_write_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); } -static inline int phy_adin2111_c45_read(const struct device *dev, uint32_t reg, - uint16_t *val) +static inline int phy_adin2111_c45_read(const struct device *dev, uint16_t devad, + uint16_t reg, uint16_t *val) { const struct phy_adin2111_config *cfg = dev->config; - return adin2111_mdio_c45_read(cfg->mdio, cfg->phy_addr, ((reg >> 16U) & 0x1FU), - (reg & 0xFFFFU), val); + return mdio_read_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); } static int phy_adin2111_reg_read(const struct device *dev, uint16_t reg_addr, @@ -192,7 +165,8 @@ static int phy_adin2111_await_phy(const struct device *dev) * it comes out from reset. */ for (count = 0U; count < ADIN2111_PHY_AWAIT_RETRY_COUNT; ++count) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_IRQ_MASK, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_MASK, &val); if (ret >= 0) { if (val != 0U) { break; @@ -233,8 +207,9 @@ int phy_adin2111_handle_phy_irq(const struct device *dev, uint16_t subsys_status; int ret; - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_SUBSYS_IRQ_STATUS, - &subsys_status); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_STATUS, + &subsys_status); if (ret < 0) { return ret; } @@ -262,15 +237,16 @@ static int phy_adin2111_sft_pd(const struct device *dev, bool enter) const uint16_t expected = enter ? ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY : 0U; uint16_t val; - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_CRSM_SFT_PD_CNTRL, - enter ? 1U : 0U); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_SFT_PD_CNTRL, + enter ? 1U : 0U); if (ret < 0) { return ret; } for (count = 0U; count < ADIN2111_PHY_SFT_PD_RETRY_COUNT; ++count) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_STAT, - &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_STAT, &val); if (ret >= 0) { if ((val & ADIN2111_CRSM_STAT_CRSM_SFT_PD_RDY) == expected) { break; @@ -368,20 +344,23 @@ static int phy_adin2111_init(const struct device *dev) } /* disable interrupts */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_CRSM_IRQ_MASK, 0U); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_MASK, 0U); if (ret < 0) { return ret; } /* enable link status change irq */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_SUBSYS_IRQ_MASK, + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_MASK, ADIN2111_PHY_SUBSYS_IRQ_STATUS_LINK_STAT_CHNG_LH); if (ret < 0) { return ret; } /* clear PHY IRQ status before enabling ADIN IRQs */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_CRSM_IRQ_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_CRSM_IRQ_STATUS, &val); if (ret < 0) { return ret; } @@ -391,13 +370,15 @@ static int phy_adin2111_init(const struct device *dev) return -ENODEV; } - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_SUBSYS_IRQ_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, + ADIN2111_PHY_SUBSYS_IRQ_STATUS, &val); if (ret < 0) { return ret; } if (!cfg->led0_en || !cfg->led1_en) { - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_LED_CNTRL, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_LED_CNTRL, &val); if (ret < 0) { return ret; } @@ -407,19 +388,20 @@ static int phy_adin2111_init(const struct device *dev) if (!cfg->led1_en) { val &= ~(ADIN2111_PHY_LED_CNTRL_LED1_EN); } - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_LED_CNTRL, val); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC1, + ADIN2111_PHY_LED_CNTRL, val); if (ret < 0) { return ret; } } /* check 2.4V support */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_PMA_STATUS, &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_PMAPMD, MDIO_PMA_B10L_STAT, &val); if (ret < 0) { return ret; } - tx_24v_supported = !!(val & ADIN2111_PHY_PMA_STATUS_B10L_TX_LVL_HI_ABLE); + tx_24v_supported = !!(val & MDIO_PMA_B10L_STAT_2V4_ABLE); LOG_INF("PHY %u 2.4V mode %s", cfg->phy_addr, tx_24v_supported ? "supported" : "not supported"); @@ -430,16 +412,15 @@ static int phy_adin2111_init(const struct device *dev) } /* config 2.4V auto-negotiation */ - ret = phy_adin2111_c45_read(dev, ADIN2111_PHY_AN_ADV_ABILITY_H, - &val); + ret = phy_adin2111_c45_read(dev, MDIO_MMD_AN, MDIO_AN_T1_ADV_H, &val); if (ret < 0) { return ret; } if (tx_24v_supported) { - val |= ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL; + val |= MDIO_AN_T1_ADV_H_10L_TX_HI; } else { - val &= ~ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_ABL; + val &= ~MDIO_AN_T1_ADV_H_10L_TX_HI; } if (cfg->tx_24v) { @@ -449,20 +430,19 @@ static int phy_adin2111_init(const struct device *dev) return -EINVAL; } - val |= ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ; + val |= MDIO_AN_T1_ADV_H_10L_TX_HI_REQ; } else { - val &= ~ADIN2111_PHY_AN_ADV_ABILITY_H_B10L_TX_LVL_HI_REQ; + val &= ~MDIO_AN_T1_ADV_H_10L_TX_HI_REQ; } - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_AN_ADV_ABILITY_H, - val); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_AN, MDIO_AN_T1_ADV_H, val); if (ret < 0) { return ret; } /* enable auto-negotiation */ - ret = phy_adin2111_c45_write(dev, ADIN2111_PHY_AN_CONTROL, - ADIN2111_PHY_AN_CONTROL_AN_EN); + ret = phy_adin2111_c45_write(dev, MDIO_MMD_AN, MDIO_AN_T1_CTRL, + MDIO_AN_T1_CTRL_EN); if (ret < 0) { return ret; } diff --git a/drivers/mdio/mdio_adin2111.c b/drivers/mdio/mdio_adin2111.c index 2d07b79ff3e..ff3cf80e43b 100644 --- a/drivers/mdio/mdio_adin2111.c +++ b/drivers/mdio/mdio_adin2111.c @@ -14,7 +14,6 @@ LOG_MODULE_REGISTER(mdio_adin2111, CONFIG_MDIO_LOG_LEVEL); #include #include #include -#include #include /* MDIO ready check retry delay */ @@ -56,9 +55,9 @@ static int mdio_adin2111_wait_ready(const struct device *dev, uint16_t reg, } -int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, - uint16_t *data) +static int mdio_adin2111_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t *data) { const struct mdio_adin2111_config *const cfg = dev->config; uint32_t rdy; @@ -96,9 +95,9 @@ int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, return ret; } -int adin2111_mdio_c45_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, - uint16_t data) +static int mdio_adin2111_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t data) { const struct mdio_adin2111_config *const cfg = dev->config; @@ -191,6 +190,8 @@ static void mdio_adin2111_bus_disable(const struct device *dev) static const struct mdio_driver_api mdio_adin2111_api = { .read = mdio_adin2111_read, .write = mdio_adin2111_write, + .read_c45 = mdio_adin2111_read_c45, + .write_c45 = mdio_adin2111_write_c45, .bus_enable = mdio_adin2111_bus_enable, .bus_disable = mdio_adin2111_bus_disable }; diff --git a/drivers/mdio/mdio_esp32.c b/drivers/mdio/mdio_esp32.c index 156a1376e71..871380c9a0a 100644 --- a/drivers/mdio/mdio_esp32.c +++ b/drivers/mdio/mdio_esp32.c @@ -143,12 +143,7 @@ static const struct mdio_esp32_dev_config mdio_esp32_dev_config_##n = { \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; -#define MDIO_ESP32_PROTOCOL_ASSERT(n) \ - BUILD_ASSERT(DT_INST_ENUM_IDX(n, protocol) == CLAUSE_22, \ - "ESP32 MDIO only supports CLAUSE_22 protocol") - #define MDIO_ESP32_DEVICE(n) \ - MDIO_ESP32_PROTOCOL_ASSERT(n); \ PINCTRL_DT_INST_DEFINE(n); \ MDIO_ESP32_CONFIG(n); \ static struct mdio_esp32_dev_data mdio_esp32_dev_data##n; \ diff --git a/drivers/mdio/mdio_gpio.c b/drivers/mdio/mdio_gpio.c index 46b99963d3c..25f67cd41b1 100644 --- a/drivers/mdio/mdio_gpio.c +++ b/drivers/mdio/mdio_gpio.c @@ -180,12 +180,7 @@ static const struct mdio_driver_api mdio_gpio_driver_api = { .mdio_gpio = GPIO_DT_SPEC_INST_GET(inst, mdio_gpios), \ }; -#define MDIO_GPIO_PROTOCOL_ASSERT(inst) \ - BUILD_ASSERT(DT_INST_ENUM_IDX(inst, protocol) == CLAUSE_22, \ - "MDIO GPIO only supports CLAUSE_22 protocol") - #define MDIO_GPIO_DEVICE(inst) \ - MDIO_GPIO_PROTOCOL_ASSERT(inst); \ MDIO_GPIO_CONFIG(inst); \ static struct mdio_gpio_data mdio_gpio_dev_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, &mdio_gpio_initialize, NULL, &mdio_gpio_dev_data_##inst, \ diff --git a/drivers/mdio/mdio_nxp_s32_netc.c b/drivers/mdio/mdio_nxp_s32_netc.c index a7c52be59ee..c8ce0e731b3 100644 --- a/drivers/mdio/mdio_nxp_s32_netc.c +++ b/drivers/mdio/mdio_nxp_s32_netc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,6 @@ LOG_MODULE_REGISTER(nxp_s32_emdio, CONFIG_MDIO_LOG_LEVEL); #define NETC_SWT_IDX 0 struct nxp_s32_mdio_config { - int protocol; const struct pinctrl_dev_config *pincfg; }; @@ -27,15 +26,9 @@ struct nxp_s32_mdio_data { static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *regval) { - const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; - if (cfg->protocol != CLAUSE_22) { - LOG_ERR("Unsupported protocol"); - return -ENOTSUP; - } - k_mutex_lock(&data->rw_mutex, K_FOREVER); status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); @@ -46,15 +39,9 @@ static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad, static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t regval) { - const struct nxp_s32_mdio_config *const cfg = dev->config; struct nxp_s32_mdio_data *data = dev->data; Std_ReturnType status; - if (cfg->protocol != CLAUSE_22) { - LOG_ERR("Unsupported protocol"); - return -ENOTSUP; - } - k_mutex_lock(&data->rw_mutex, K_FOREVER); status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, regad, regval); k_mutex_unlock(&data->rw_mutex); @@ -96,7 +83,6 @@ PINCTRL_DT_DEFINE(MDIO_NODE); static struct nxp_s32_mdio_data nxp_s32_mdio0_data; static const struct nxp_s32_mdio_config nxp_s32_mdio0_cfg = { - .protocol = DT_ENUM_IDX(MDIO_NODE, protocol), .pincfg = PINCTRL_DT_DEV_CONFIG_GET(MDIO_NODE), }; diff --git a/drivers/mdio/mdio_sam.c b/drivers/mdio/mdio_sam.c index fef75c3c42d..078f12c9338 100644 --- a/drivers/mdio/mdio_sam.c +++ b/drivers/mdio/mdio_sam.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 IP-Logix Inc. + * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +14,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(mdio_sam, CONFIG_MDIO_LOG_LEVEL); @@ -31,11 +33,11 @@ struct mdio_sam_dev_data { struct mdio_sam_dev_config { Gmac * const regs; const struct pinctrl_dev_config *pcfg; - int protocol; }; static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, - uint8_t rw, uint16_t data_in, uint16_t *data_out) + enum mdio_opcode op, bool c45, uint16_t data_in, + uint16_t *data_out) { const struct mdio_sam_dev_config *const cfg = dev->config; struct mdio_sam_dev_data *const data = dev->data; @@ -44,24 +46,12 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, k_sem_take(&data->sem, K_FOREVER); /* Write mdio transaction */ - if (cfg->protocol == CLAUSE_45) { - cfg->regs->GMAC_MAN = (GMAC_MAN_OP(rw ? 0x2 : 0x3)) - | GMAC_MAN_WTN(0x02) - | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(regad) - | GMAC_MAN_DATA(data_in); - - } else if (cfg->protocol == CLAUSE_22) { - cfg->regs->GMAC_MAN = GMAC_MAN_CLTTO - | (GMAC_MAN_OP(rw ? 0x2 : 0x1)) - | GMAC_MAN_WTN(0x02) - | GMAC_MAN_PHYA(prtad) - | GMAC_MAN_REGA(regad) - | GMAC_MAN_DATA(data_in); - - } else { - LOG_ERR("Unsupported protocol"); - } + cfg->regs->GMAC_MAN = (c45 ? 0U : GMAC_MAN_CLTTO) + | GMAC_MAN_OP(op) + | GMAC_MAN_WTN(0x02) + | GMAC_MAN_PHYA(prtad) + | GMAC_MAN_REGA(regad) + | GMAC_MAN_DATA(data_in); /* Wait until done */ while (!(cfg->regs->GMAC_NSR & GMAC_NSR_IDLE)) { @@ -87,13 +77,45 @@ static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad, static int mdio_sam_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) { - return mdio_transfer(dev, prtad, regad, 1, 0, data); + return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_READ, false, + 0, data); } static int mdio_sam_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data) { - return mdio_transfer(dev, prtad, regad, 0, data, NULL); + return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_WRITE, false, + data, NULL); +} + +static int mdio_sam_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t *data) +{ + int err; + + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, + regad, NULL); + if (!err) { + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_READ, true, + 0, data); + } + + return err; +} + +static int mdio_sam_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t data) +{ + int err; + + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, + regad, NULL); + if (!err) { + err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_WRITE, true, + data, NULL); + } + + return err; } static void mdio_sam_bus_enable(const struct device *dev) @@ -126,6 +148,8 @@ static int mdio_sam_initialize(const struct device *dev) static const struct mdio_driver_api mdio_sam_driver_api = { .read = mdio_sam_read, .write = mdio_sam_write, + .read_c45 = mdio_sam_read_c45, + .write_c45 = mdio_sam_write_c45, .bus_enable = mdio_sam_bus_enable, .bus_disable = mdio_sam_bus_disable, }; @@ -134,7 +158,6 @@ static const struct mdio_driver_api mdio_sam_driver_api = { static const struct mdio_sam_dev_config mdio_sam_dev_config_##n = { \ .regs = (Gmac *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .protocol = DT_INST_ENUM_IDX(n, protocol), \ }; #define MDIO_SAM_DEVICE(n) \ diff --git a/dts/bindings/mdio/mdio-controller.yaml b/dts/bindings/mdio/mdio-controller.yaml index aed844bf8f8..b944d0a6ee8 100644 --- a/dts/bindings/mdio/mdio-controller.yaml +++ b/dts/bindings/mdio/mdio-controller.yaml @@ -6,19 +6,3 @@ include: base.yaml bus: mdio - -properties: - protocol: - type: string - description: | - MDIO bus framing protocol to use for communication. Most devices - support clause 22. - - - clause 22: IEEE802.3 clause 22 frame format - - clause 45: IEEE802.3 clause 45 frame format - - micrel SMI: Micrel Serial Management Interface frame format - enum: - - "clause 22" - - "clause 45" - - "micrel SMI" - default: "clause 22" diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index e862a653e9b..09714cd2743 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -69,7 +69,6 @@ mdio: mdio { compatible = "espressif,esp32-mdio"; - protocol = "clause 22"; clocks = <&rtc ESP32_EMAC_MODULE>; status = "disabled"; }; diff --git a/include/zephyr/drivers/mdio.h b/include/zephyr/drivers/mdio.h index f02428c0602..1d030c0f586 100644 --- a/include/zephyr/drivers/mdio.h +++ b/include/zephyr/drivers/mdio.h @@ -32,14 +32,6 @@ extern "C" { * These are for internal use only, so skip these in * public documentation. */ - -/** Order of items in this enum must match the `protocol` dts binding */ -enum MDIO_PROTOCOL { - CLAUSE_22 = 0, - CLAUSE_45 = 1, - MICREL_SMI = 2, -}; - __subsystem struct mdio_driver_api { /** Enable the MDIO bus device */ void (*bus_enable)(const struct device *dev); @@ -54,6 +46,14 @@ __subsystem struct mdio_driver_api { /** Write data to MDIO bus */ int (*write)(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); + + /** Read data from MDIO bus using Clause 45 access */ + int (*read_c45)(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data); + + /** Write data to MDIO bus using Clause 45 access */ + int (*write_c45)(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data); }; /** * @endcond @@ -105,6 +105,7 @@ static inline void z_impl_mdio_bus_disable(const struct device *dev) * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported */ __syscall int mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data); @@ -115,6 +116,10 @@ static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; + if (api->read == NULL) { + return -ENOSYS; + } + return api->read(dev, prtad, regad, data); } @@ -133,6 +138,7 @@ static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad, * @retval 0 If successful. * @retval -EIO General input / output error. * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write is not supported */ __syscall int mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data); @@ -143,9 +149,81 @@ static inline int z_impl_mdio_write(const struct device *dev, uint8_t prtad, const struct mdio_driver_api *api = (const struct mdio_driver_api *)dev->api; + if (api->write == NULL) { + return -ENOSYS; + } + return api->write(dev, prtad, regad, data); } +/** + * @brief Read from MDIO Bus using Clause 45 access + * + * This routine provides an interface to perform a read on the MDIO bus using + * IEEE 802.3 Clause 45 access. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad Device address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write using Clause 45 access is not supported + */ +__syscall int mdio_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t *data); + +static inline int z_impl_mdio_read_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t *data) +{ + const struct mdio_driver_api *api = + (const struct mdio_driver_api *)dev->api; + + if (api->read_c45 == NULL) { + return -ENOSYS; + } + + return api->read_c45(dev, prtad, devad, regad, data); +} + +/** + * @brief Write to MDIO bus using Clause 45 access + * + * This routine provides an interface to perform a write on the MDIO bus using + * IEEE 802.3 Clause 45 access. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad Device address + * @param[in] regad Register address + * @param[in] data Data to write + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if write using Clause 45 access is not supported + */ +__syscall int mdio_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, uint16_t data); + +static inline int z_impl_mdio_write_c45(const struct device *dev, uint8_t prtad, + uint8_t devad, uint16_t regad, + uint16_t data) +{ + const struct mdio_driver_api *api = + (const struct mdio_driver_api *)dev->api; + + if (api->write_c45 == NULL) { + return -ENOSYS; + } + + return api->write_c45(dev, prtad, devad, regad, data); +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/mdio/mdio_adin2111.h b/include/zephyr/drivers/mdio/mdio_adin2111.h deleted file mode 100644 index bf971861434..00000000000 --- a/include/zephyr/drivers/mdio/mdio_adin2111.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ -#define ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Read from MDIO Bus using Clause 45 access - * - * @note The caller is responsible for device lock. - * Shall not be called from ISR. - * - * @param[in] dev MDIO device. - * @param[in] prtad Port address. - * @param[in] devad Device address. - * @param[in] regad Register address. - * @param[out] data Pointer to receive read data. - * - * @retval 0 If successful. - * @retval -EIO General input / output error. - * @retval -ETIMEDOUT If transaction timedout on the bus. - * @retval <0 Error, a negative errno code. - */ -int adin2111_mdio_c45_read(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, uint16_t *data); - -/** - * @brief Write to MDIO bus using Clause 45 access - * - * @note The caller is responsible for device lock. - * Shall not be called from ISR. - * - * @param[in] dev MDIO device. - * @param[in] prtad Port address. - * @param[in] devad Device address. - * @param[in] regad Register address. - * @param[in] data Data to write. - * - * @retval 0 If successful. - * @retval -EIO General input / output error. - * @retval -ETIMEDOUT If transaction timedout on the bus. - * @retval <0 Error, a negative errno code. - */ -int adin2111_mdio_c45_write(const struct device *dev, uint8_t prtad, - uint8_t devad, uint16_t regad, uint16_t data); - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_DRIVERS_MDIO_ADIN2111_H__ */ diff --git a/include/zephyr/net/mdio.h b/include/zephyr/net/mdio.h new file mode 100644 index 00000000000..e7161a7a766 --- /dev/null +++ b/include/zephyr/net/mdio.h @@ -0,0 +1,233 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for IEEE 802.3 management interface + */ + +#ifndef ZEPHYR_INCLUDE_NET_MDIO_H_ +#define ZEPHYR_INCLUDE_NET_MDIO_H_ + +/** + * @brief Definitions for IEEE 802.3 management interface + * @defgroup ethernet_mdio IEEE 802.3 management interface + * @ingroup ethernet + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** MDIO transaction operation code */ +enum mdio_opcode { + /** IEEE 802.3 22.2.4.5.4 write operation */ + MDIO_OP_C22_WRITE = 1, + + /** IEEE 802.3 22.2.4.5.4 read operation */ + MDIO_OP_C22_READ = 2, + + /** IEEE 802.3 45.3.4 address operation */ + MDIO_OP_C45_ADDRESS = 0, + + /** IEEE 802.3 45.3.4 write operation */ + MDIO_OP_C45_WRITE = 1, + + /** IEEE 802.3 45.3.4 post-read-increment-address operation */ + MDIO_OP_C45_READ_INC = 2, + + /** IEEE 802.3 45.3.4 read operation */ + MDIO_OP_C45_READ = 3 +}; + +/* MDIO Manageable Device addresses */ +/** Physical Medium Attachment / Physical Medium Dependent */ +#define MDIO_MMD_PMAPMD 0x01U +/** WAN Interface Sublayer */ +#define MDIO_MMD_WIS 0x02U +/** Physical Coding Sublayer */ +#define MDIO_MMD_PCS 0x03U +/** PHY Extender Sublayer */ +#define MDIO_MMD_PHYXS 0x04U +/** DTE Extender Sublayer */ +#define MDIO_MMD_DTEXS 0x05U +/** Transmission Convergence */ +#define MDIO_MMD_TC 0x06U +/** Auto-negotiation */ +#define MDIO_MMD_AN 0x07U +/** Separated PMA (1) */ +#define MDIO_MMD_SEPARATED_PMA1 0x08U +/** Separated PMA (2) */ +#define MDIO_MMD_SEPARATED_PMA2 0x09U +/** Separated PMA (3) */ +#define MDIO_MMD_SEPARATED_PMA3 0x0AU +/** Separated PMA (4) */ +#define MDIO_MMD_SEPARATED_PMA4 0x0BU +/** Clause 22 extension */ +#define MDIO_MMD_C22EXT 0x1DU +/** Vendor Specific 1 */ +#define MDIO_MMD_VENDOR_SPECIFIC1 0x1EU +/** Vendor Specific 2 */ +#define MDIO_MMD_VENDOR_SPECIFIC2 0x1FU + +/* MDIO generic registers */ +/** Control 1 */ +#define MDIO_CTRL1 0x0000U +/** Status 1 */ +#define MDIO_STAT1 0x0001U +/** Device identifier (1) */ +#define MDIO_DEVID1 0x0002U +/** Device identifier (2) */ +#define MDIO_DEVID2 0x0003U +/** Speed ability */ +#define MDIO_SPEED 0x0004U +/** Devices in package (1) */ +#define MDIO_DEVS1 0x0005U +/** Devices in package (2) */ +#define MDIO_DEVS2 0x0006U +/** Control 2 */ +#define MDIO_CTRL2 0x0007U +/** Status 2 */ +#define MDIO_STAT2 0x0008U +/** Package identifier (1) */ +#define MDIO_PKGID1 0x000EU +/** Package identifier (2) */ +#define MDIO_PKGID2 0x000FU + + +/* BASE-T1 registers */ +/** BASE-T1 Auto-negotiation control */ +#define MDIO_AN_T1_CTRL 0x0200U +/** BASE-T1 Auto-negotiation status */ +#define MDIO_AN_T1_STAT 0x0201U +/** BASE-T1 Auto-negotiation advertisement register [15:0] */ +#define MDIO_AN_T1_ADV_L 0x0202U +/** BASE-T1 Auto-negotiation advertisement register [31:16] */ +#define MDIO_AN_T1_ADV_M 0x0203U +/** BASE-T1 Auto-negotiation advertisement register [47:32] */ +#define MDIO_AN_T1_ADV_H 0x0204U + +/* BASE-T1 Auto-negotiation Control register */ +/** Auto-negotiation Restart */ +#define MDIO_AN_T1_CTRL_RESTART BIT(9) +/** Auto-negotiation Enable */ +#define MDIO_AN_T1_CTRL_EN BIT(12) + +/* BASE-T1 Auto-negotiation Status register */ +/** Link Status */ +#define MDIO_AN_T1_STAT_LINK_STATUS BIT(2) +/** Auto-negotiation Ability */ +#define MDIO_AN_T1_STAT_ABLE BIT(3) +/** Auto-negotiation Remote Fault */ +#define MDIO_AN_T1_STAT_REMOTE_FAULT BIT(4) +/** Auto-negotiation Complete */ +#define MDIO_AN_T1_STAT_COMPLETE BIT(5) +/** Page Received */ +#define MDIO_AN_T1_STAT_PAGE_RX BIT(6) + +/* BASE-T1 Auto-negotiation Advertisement register [15:0] */ +/** Pause Ability */ +#define MDIO_AN_T1_ADV_L_PAUSE_CAP BIT(10) +/** Pause Ability */ +#define MDIO_AN_T1_ADV_L_PAUSE_ASYM BIT(11) +/** Force Master/Slave Configuration */ +#define MDIO_AN_T1_ADV_L_FORCE_MS BIT(12) +/** Remote Fault */ +#define MDIO_AN_T1_ADV_L_REMOTE_FAULT BIT(13) +/** Acknowledge (ACK) */ +#define MDIO_AN_T1_ADV_L_ACK BIT(14) +/** Next Page Request */ +#define MDIO_AN_T1_ADV_L_NEXT_PAGE_REQ BIT(15) + +/* BASE-T1 Auto-negotiation Advertisement register [31:16] */ +/** 10BASE-T1L Ability */ +#define MDIO_AN_T1_ADV_M_B10L BIT(14) +/** Master/slave Configuration */ +#define MDIO_AN_T1_ADV_M_MST BIT(4) + +/* BASE-T1 Auto-negotiation Advertisement register [47:32] */ +/* 10BASE-T1L High Level Transmit Operating Mode Request */ +#define MDIO_AN_T1_ADV_H_10L_TX_HI_REQ BIT(12) +/* 10BASE-T1L High Level Transmit Operating Mode Ability */ +#define MDIO_AN_T1_ADV_H_10L_TX_HI BIT(13) + + +/* 10BASE-T1L registers */ +/** 10BASE-T1L PMA control */ +#define MDIO_PMA_B10L_CTRL 0x08F6U +/** 10BASE-T1L PMA status */ +#define MDIO_PMA_B10L_STAT 0x08F7U +/** 10BASE-T1L PMA link status*/ +#define MDIO_PMA_B10L_LINK_STAT 0x8302U +/** 10BASE-T1L PCS control */ +#define MDIO_PCS_B10L_CTRL 0x08E6U +/** 10BASE-T1L PCS status */ +#define MDIO_PCS_B10L_STAT 0x08E7U + +/* 10BASE-T1L PMA control register */ +/** 10BASE-T1L Transmit Disable Mode */ +#define MDIO_PMA_B10L_CTRL_TX_DIS_MODE_EN BIT(14) +/** 10BASE-T1L Transmit Voltage Amplitude Control */ +#define MDIO_PMA_B10L_CTRL_TX_LVL_HI BIT(12) +/** 10BASE-T1L EEE Enable */ +#define MDIO_PMA_B10L_CTRL_EEE BIT(10) +/** 10BASE-T1L PMA Loopback */ +#define MDIO_PMA_B10L_CTRL_LB_PMA_LOC_EN BIT(0) + +/* 10BASE-T1L PMA status register */ +/** 10BASE-T1L PMA receive link up */ +#define MDIO_PMA_B10L_STAT_LINK BIT(0) +/** 10BASE-T1L Fault condition detected */ +#define MDIO_PMA_B10L_STAT_FAULT BIT(1) +/** 10BASE-T1L Receive polarity is reversed */ +#define MDIO_PMA_B10L_STAT_POLARITY BIT(2) +/** 10BASE-T1L Able to detect fault on receive path */ +#define MDIO_PMA_B10L_STAT_RECV_FAULT BIT(9) +/** 10BASE-T1L PHY has EEE ability */ +#define MDIO_PMA_B10L_STAT_EEE BIT(10) +/** 10BASE-T1L PMA has low-power ability */ +#define MDIO_PMA_B10L_STAT_LOW_POWER BIT(11) +/** 10BASE-T1L PHY has 2.4 Vpp operating mode ability */ +#define MDIO_PMA_B10L_STAT_2V4_ABLE BIT(12) +/** 10BASE-T1L PHY has loopback ability */ +#define MDIO_PMA_B10L_STAT_LB_ABLE BIT(13) + +/* 10BASE-T1L PMA link status*/ +/** 10BASE-T1L Remote Receiver Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_REM_RCVR_STAT_OK_LL BIT(9) +/** 10BASE-T1L Remote Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_REM_RCVR_STAT_OK BIT(8) +/** 10BASE-T1L Local Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LOC_RCVR_STAT_OK_LL BIT(7) +/** 10BASE-T1L Local Receiver Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LOC_RCVR_STAT_OK BIT(6) +/** 10BASE-T1L Descrambler Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_DSCR_STAT_OK_LL BIT(5) +/** 10BASE-T1L Descrambler Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_DSCR_STAT_OK BIT(4) +/** 10BASE-T1L Link Status OK Latch Low */ +#define MDIO_PMA_B10L_LINK_STAT_LINK_STAT_OK_LL BIT(1) +/** 10BASE-T1L Link Status OK */ +#define MDIO_PMA_B10L_LINK_STAT_LINK_STAT_OK BIT(0) + +/* 10BASE-T1L PCS control */ +/** 10BASE-T1L PCS Loopback Enable */ +#define MDIO_PCS_B10L_CTRL_LB_PCS_EN BIT(14) + +/* 10BASE-T1L PCS status */ +/** 10BASE-T1L PCS Descrambler Status */ +#define MDIO_PCS_B10L_STAT_DSCR_STAT_OK_LL BIT(2) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_MDIO_H_ */