Skip to content

drivers: ethernet: phy: add driver for ksz9131, update ksz8081 with interrupt support #90711

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

TonyHan11
Copy link
Contributor

@TonyHan11 TonyHan11 commented May 28, 2025

This PR includes:

  • add the driver for Microchip KSZ9131 Ethernet PHY
  • add interrupt mode support for KSZ8081

@pdgendt
Copy link
Collaborator

pdgendt commented May 28, 2025

Comment on lines 17 to 22
microchip,interface-type:
type: string
required: true
description: Which type of phy connection the phy is set up for
enum:
- "rgmii"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems not being used in code, please remove.

Comment on lines 365 to 372
if (mutual_capabilities & MII_ADVERTISE_100_FULL) {
state->speed = LINK_FULL_100BASE_T;
} else if (mutual_capabilities & MII_ADVERTISE_100_HALF) {
state->speed = LINK_HALF_100BASE_T;
} else if (mutual_capabilities & MII_ADVERTISE_10_FULL) {
state->speed = LINK_FULL_10BASE_T;
} else if (mutual_capabilities & MII_ADVERTISE_10_HALF) {
state->speed = LINK_HALF_10BASE_T;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these LINK_*_*BASE_T got changed to LINK_*_*BASE

Comment on lines 275 to 313
if (adv_speeds & LINK_FULL_10BASE_T) {
anar |= MII_ADVERTISE_10_FULL;
} else {
anar &= ~MII_ADVERTISE_10_FULL;
}

if (adv_speeds & LINK_HALF_10BASE_T) {
anar |= MII_ADVERTISE_10_HALF;
} else {
anar &= ~MII_ADVERTISE_10_HALF;
}

if (adv_speeds & LINK_FULL_100BASE_T) {
anar |= MII_ADVERTISE_100_FULL;
} else {
anar &= ~MII_ADVERTISE_100_FULL;
}

if (adv_speeds & LINK_HALF_100BASE_T) {
anar |= MII_ADVERTISE_100_HALF;
} else {
anar &= ~MII_ADVERTISE_100_HALF;
}

BREAK_IF_ERR(ret, ksz9131_write(dev, MII_ANAR, anar));

BREAK_IF_ERR(ret, ksz9131_read(dev, MII_1KTCR, &c1kt));

if (adv_speeds & LINK_FULL_1000BASE_T) {
c1kt |= MII_ADVERTISE_1000_FULL;
} else {
c1kt &= ~MII_ADVERTISE_1000_FULL;
}

if (adv_speeds & LINK_HALF_1000BASE_T) {
c1kt |= MII_ADVERTISE_1000_HALF;
} else {
c1kt &= ~MII_ADVERTISE_1000_HALF;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

const struct mchp_ksz9131_config *const cfg = dev->config;
int ret = mdio_read(cfg->mdio, cfg->phy_addr, reg_addr, value);

if (ret) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (ret) {
if (ret < 0) {

Please change everywhere, ret is negative on error.

@TonyHan11 TonyHan11 force-pushed the phy_ksz9131_ksz8081 branch from 6944d51 to 5055226 Compare May 28, 2025 08:09
@TonyHan11
Copy link
Contributor Author

@pdgendt An entry for ksz9131 added to tests/drivers/build_all/ethernet/app.overlay, thanks.

@maass-hamburg
Copy link
Collaborator

@TonyHan11 pls add PR description and address the things from sonarqube

@TonyHan11
Copy link
Contributor Author

@maass-hamburg updated with removing the unused property, renaming LINK_*BASED_T and fixing if (ret), thank you very much.

@TonyHan11 TonyHan11 force-pushed the phy_ksz9131_ksz8081 branch from 5055226 to cfd8c64 Compare May 29, 2025 01:21
return;
}
#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */

/* TODO change this to GPIO interrupt driven */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo can be removed


/* Lock mutex */
ret = k_mutex_lock(&data->mutex, K_FOREVER);
if (ret) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always use ret < 0 when checking for errors

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
if (config->interrupt_gpio.port) {
rc = phy_mc_ksz8081_clear_interrupt(data);
if (rc) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

Comment on lines 619 to 651
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
do {
if (!config->interrupt_gpio.port) {
phy_mc_ksz8081_monitor_work_handler(&data->phy_monitor_work.work);
break;
}

/* Configure interrupt pin */
ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_INPUT);
if (ret) {
break;
}

gpio_init_callback(&data->gpio_callback, phy_mc_ksz8081_interrupt_handler,
BIT(config->interrupt_gpio.pin));
if (ret) {
break;
}

ret = gpio_add_callback_dt(&config->interrupt_gpio, &data->gpio_callback);
if (ret) {
break;
}

ret = phy_mc_ksz8081_config_interrupt(dev);
if (ret) {
break;
}

ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio,
GPIO_INT_EDGE_TO_ACTIVE);
} while (0);
if (ret) {
LOG_ERR("PHY (%d) config interrupt failed", config->addr);
}
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe make this a separate function, also in zephyr we prefer using goto instead of do while (0) loops.

Comment on lines 21 to 26
#define BREAK_IF_ERR(ret, fun) do { \
ret = fun; \
if (ret < 0) { \
break; \
} \
} while (0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this won't work the break will only break out of the inner do while 0 loop. Also this makes it more difficult to read, please use simple goto instead

@TonyHan11 TonyHan11 force-pushed the phy_ksz9131_ksz8081 branch 4 times, most recently from 1ac4658 to e7778f7 Compare June 3, 2025 04:41
@TonyHan11
Copy link
Contributor Author

@maass-hamburg
Thank you for your comments. Commits updated with the following changes:

  • using goto instead of do while (0)
  • update if (ret) to if (ret < 0)
  • fix the issues reported by SonarQube Cloud
  • remove comments TODO change this to GPIO interrupt driven

default y
depends on DT_HAS_MICROCHIP_KSZ9131_ENABLED
depends on MDIO
depends on GPIO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPIO is probably not required without reset and irq pin.
look at config PHY_REALTEK_RTL8211F how to change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, thanks.

@TonyHan11 TonyHan11 force-pushed the phy_ksz9131_ksz8081 branch from e7778f7 to ffe8e46 Compare June 4, 2025 01:15
TonyHan11 added 4 commits June 4, 2025 09:28
Add support for KSZ9131 (Gigabit Ethernet Transceiver with RGMII Support).
As first starter, 100MBit/s mode is tested.
https://www.microchip.com/en-us/product/ksz9131

Signed-off-by: Tony Han <tony.han@microchip.com>
Add build tests for Microchip KSZ9131.

Signed-off-by: Tony Han <tony.han@microchip.com>
Enable Link-Up and Link-Down interrupts. On the interrupt handling
the monitor work is scheduled to update the link status and calling
corresponding callback routine.

Signed-off-by: Tony Han <tony.han@microchip.com>
Enable Link-Up and Link-Down interrupts. On the interrupt handling
the monitor work is scheduled to update the link status and calling
corresponding callback routine.

Signed-off-by: Tony Han <tony.han@microchip.com>
Copy link

sonarqubecloud bot commented Jun 4, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants