Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 4 additions & 51 deletions drivers/ethernet/eth_nxp_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,51 +459,12 @@ static void eth_nxp_enet_rx_thread(struct k_work *work)
ENET_EnableInterrupts(data->base, kENET_RxFrameInterrupt);
}

static int nxp_enet_phy_configure(const struct device *phy, uint8_t phy_mode)
{
enum phy_link_speed speeds = LINK_HALF_10BASE | LINK_FULL_10BASE |
LINK_HALF_100BASE | LINK_FULL_100BASE;
int ret;
struct phy_link_state state;

if (COND_CODE_1(IS_ENABLED(CONFIG_ETH_NXP_ENET_1G),
(phy_mode == NXP_ENET_RGMII_MODE), (0))) {
speeds |= (LINK_HALF_1000BASE | LINK_FULL_1000BASE);
}

/* Configure the PHY */
ret = phy_configure_link(phy, speeds, 0);
if (ret == -EALREADY) {
return 0;
} else if (ret == -ENOTSUP || ret == -ENOSYS) {
phy_get_link_state(phy, &state);

if (state.is_up) {
LOG_WRN("phy_configure_link returned %d, but link is up. "
"Speed: %s, %s-duplex",
ret,
PHY_LINK_IS_SPEED_1000M(state.speed) ? "1 Gbits" :
PHY_LINK_IS_SPEED_100M(state.speed) ? "100 Mbits" : "10 Mbits",
PHY_LINK_IS_FULL_DUPLEX(state.speed) ? "full" : "half");
} else {
LOG_ERR("phy_configure_link returned %d and link is down.", ret);
return -ENETDOWN;
}
} else if (ret) {
LOG_ERR("phy_configure_link failed with error: %d", ret);
return ret;
}

return 0;
}

static void nxp_enet_phy_cb(const struct device *phy,
struct phy_link_state *state,
void *eth_dev)
{
const struct device *dev = eth_dev;
struct nxp_enet_mac_data *data = dev->data;
const struct nxp_enet_mac_config *config = dev->config;
enet_mii_speed_t speed;
enet_mii_duplex_t duplex;

Expand All @@ -527,16 +488,13 @@ static void nxp_enet_phy_cb(const struct device *phy,
}

ENET_SetMII(data->base, speed, duplex);
}

LOG_INF("Link is %s", state->is_up ? "up" : "down");

if (!state->is_up) {
net_eth_carrier_off(data->iface);
nxp_enet_phy_configure(phy, config->phy_mode);
} else {
net_eth_carrier_on(data->iface);
} else {
net_eth_carrier_off(data->iface);
}

LOG_INF("Link is %s", state->is_up ? "up" : "down");
}

static void eth_nxp_enet_iface_init(struct net_if *iface)
Expand Down Expand Up @@ -813,11 +771,6 @@ static int eth_nxp_enet_init(const struct device *dev)

ENET_ActiveRead(data->base);

err = nxp_enet_phy_configure(config->phy_dev, config->phy_mode);
if (err) {
return err;
}

LOG_DBG("%s MAC %02x:%02x:%02x:%02x:%02x:%02x",
dev->name,
data->mac_addr[0], data->mac_addr[1],
Expand Down
7 changes: 0 additions & 7 deletions drivers/ethernet/eth_xilinx_axienet.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,13 +534,6 @@ static int xilinx_axienet_probe(const struct device *dev)
XILINX_AXIENET_RECEIVER_CONFIGURATION_FLOW_CONTROL_OFFSET,
XILINX_AXIENET_RECEIVER_CONFIGURATION_FLOW_CONTROL_EN_MASK);

/* at time of writing, hardware does not support half duplex */
err = phy_configure_link(config->phy,
LINK_FULL_10BASE | LINK_FULL_100BASE | LINK_FULL_1000BASE, 0);
if (err) {
LOG_WRN("Could not configure PHY: %d", -err);
}

LOG_INF("RX Checksum offloading %s",
config->have_rx_csum_offload ? "requested" : "disabled");
LOG_INF("TX Checksum offloading %s",
Expand Down
5 changes: 5 additions & 0 deletions drivers/ethernet/phy/phy_microchip_ksz8081.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct mc_ksz8081_config {
uint8_t addr;
const struct device *mdio_dev;
enum ksz8081_interface phy_iface;
enum phy_link_speed default_speeds;
Copy link
Contributor

Choose a reason for hiding this comment

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

how about using conventional name supported_speeds or link_speeds?

Copy link
Member Author

Choose a reason for hiding this comment

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

this is only used for configuring the phy on init, so these are the speeds that the phy will use by default, you can still configure the speeds later with phy_configure_link() and also set speeds that were not in default_speeds. By the way this is also how it is in phy_mii and this pr is extending it's functionality to the other phys

Copy link
Contributor

Choose a reason for hiding this comment

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

this is only used for configuring the phy on init, so these are the speeds that the phy will use by default, you can still configure the speeds later with phy_configure_link() and also set speeds that were not in default_speeds. By the way this is also how it is in phy_mii and this pr is extending it's functionality to the other phys

Sorry, I missed the reference to the phy_mii PR earlier. My rationale is as follows:

Currently, default_speeds is generated based on what the specific PHY driver defines in the device tree or YAML, and it is used as a parameter for phy_configure_link().

For example:
default-speeds:
default: ["10BASE Half-Duplex", "10BASE Full-Duplex", "100BASE Half-Duplex",
"100BASE Full-Duplex"]

In practice, users or customers interpret these values as the supported speeds of the specific PHY. Referring to them as "default" is not ideal, as "default" suggests a fallback or initial value, rather than the complete set of speeds the PHY is capable of.

Copy link
Member Author

Choose a reason for hiding this comment

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

if the user doesn't provide default-speeds, we will do auto negotiation with all supported speeds of the phy. That btw is also the default behavior of the phy (based on the registers) if we don't configure it.

also the phy_mii phy was doing phy_configure_link() with all supported speeds before #89210 and to preserve that behavior, these got set as the default, if the user didn't changed the prop in the dts.

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
const struct gpio_dt_spec reset_gpio;
#endif
Expand Down Expand Up @@ -489,6 +490,9 @@ static int phy_mc_ksz8081_init(const struct device *dev)
k_work_init_delayable(&data->phy_monitor_work,
phy_mc_ksz8081_monitor_work_handler);

/* Advertise default speeds */
phy_mc_ksz8081_cfg_link(dev, config->default_speeds, 0);

return 0;
}

Expand Down Expand Up @@ -519,6 +523,7 @@ static DEVICE_API(ethphy, mc_ksz8081_phy_api) = {
.addr = DT_INST_REG_ADDR(n), \
.mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
.phy_iface = DT_INST_ENUM_IDX(n, microchip_interface_type), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
RESET_GPIO(n) \
INTERRUPT_GPIO(n) \
}; \
Expand Down
4 changes: 4 additions & 0 deletions drivers/ethernet/phy/phy_microchip_vsc8541.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct mc_vsc8541_config {
uint8_t addr;
const struct device *mdio_dev;
enum vsc8541_interface microchip_interface_type;
enum phy_link_speed default_speeds;
uint8_t rgmii_rx_clk_delay;
uint8_t rgmii_tx_clk_delay;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
Expand Down Expand Up @@ -316,6 +317,8 @@ static int phy_mc_vsc8541_init(const struct device *dev)

k_thread_name_set(&data->link_monitor_thread, "phy-link-mon");

phy_mc_vsc8541_cfg_link(dev, cfg->default_speeds, 0);

return 0;
}

Expand Down Expand Up @@ -546,6 +549,7 @@ static DEVICE_API(ethphy, mc_vsc8541_phy_api) = {
.microchip_interface_type = DT_INST_ENUM_IDX(n, microchip_interface_type), \
.rgmii_rx_clk_delay = DT_INST_PROP(n, microchip_rgmii_rx_clk_delay), \
.rgmii_tx_clk_delay = DT_INST_PROP(n, microchip_rgmii_tx_clk_delay), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
RESET_GPIO(n) INTERRUPT_GPIO(n)}; \
\
static struct mc_vsc8541_data mc_vsc8541_##n##_data; \
Expand Down
12 changes: 2 additions & 10 deletions drivers/ethernet/phy/phy_mii.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,24 +549,16 @@ 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, \
BUILD_ASSERT(PHY_INST_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), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
.mdio = UTIL_AND(UTIL_NOT(IS_FIXED_LINK(n)), \
DEVICE_DT_GET(DT_INST_BUS(n))) \
};
Expand Down
8 changes: 8 additions & 0 deletions drivers/ethernet/phy/phy_mii.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
#include <zephyr/net/phy.h>
#include <zephyr/net/mii.h>

#define PHY_INST_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))

static inline int phy_mii_set_anar_reg(const struct device *dev, enum phy_link_speed adv_speeds)
{
uint32_t anar_reg = 0U;
Expand Down
38 changes: 6 additions & 32 deletions drivers/ethernet/phy/phy_qualcomm_ar8031.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ LOG_MODULE_REGISTER(phy_qc_ar8031, CONFIG_PHY_LOG_LEVEL);

struct qc_ar8031_config {
uint8_t addr;
bool fixed_link;
bool enable_eee;
int fixed_speed;
enum phy_link_speed default_speeds;
const struct device *mdio_dev;
};

Expand Down Expand Up @@ -414,36 +413,12 @@ static int qc_ar8031_init(const struct device *dev)
}
}

/* Fixed Link */
if (cfg->fixed_link) {
/* Disable isolate */
ret = qc_ar8031_read(dev, MII_BMCR, &reg_value);
if (ret) {
return -EIO;
}
reg_value &= ~MII_BMCR_ISOLATE;
ret = qc_ar8031_write(dev, MII_BMCR, reg_value);
if (ret) {
return -EIO;
}

const static int speed_to_phy_link_speed[] = {
LINK_HALF_10BASE, LINK_FULL_10BASE, LINK_HALF_100BASE,
LINK_FULL_100BASE, LINK_HALF_1000BASE, LINK_FULL_1000BASE,
};
/* Advertise default speeds */
qc_ar8031_cfg_link(dev, cfg->default_speeds, 0);

data->state.speed = speed_to_phy_link_speed[cfg->fixed_speed];
data->state.is_up = true;
} else { /* Auto negotiation */
/* Advertise all speeds */
qc_ar8031_cfg_link(dev, LINK_HALF_10BASE | LINK_FULL_10BASE |
LINK_HALF_100BASE | LINK_FULL_100BASE |
LINK_HALF_1000BASE | LINK_FULL_1000BASE, 0);
k_work_init_delayable(&data->monitor_work, monitor_work_handler);

k_work_init_delayable(&data->monitor_work, monitor_work_handler);

monitor_work_handler(&data->monitor_work.work);
}
monitor_work_handler(&data->monitor_work.work);

return 0;
}
Expand All @@ -459,9 +434,8 @@ static DEVICE_API(ethphy, ar8031_driver_api) = {
#define AR8031_CONFIG(n) \
static const struct qc_ar8031_config qc_ar8031_config_##n = { \
.addr = DT_INST_REG_ADDR(n), \
.fixed_link = DT_INST_NODE_HAS_PROP(n, fixed_link), \
.fixed_speed = DT_INST_ENUM_IDX_OR(n, fixed_link, 0), \
.mdio_dev = DEVICE_DT_GET(DT_INST_BUS(n)), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
.enable_eee = DT_INST_NODE_HAS_PROP(n, eee_en), \
};

Expand Down
5 changes: 5 additions & 0 deletions drivers/ethernet/phy/phy_realtek_rtl8211f.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
struct rt_rtl8211f_config {
uint8_t addr;
const struct device *mdio_dev;
enum phy_link_speed default_speeds;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
const struct gpio_dt_spec reset_gpio;
#endif
Expand Down Expand Up @@ -599,6 +600,9 @@ static int phy_rt_rtl8211f_init(const struct device *dev)
phy_rt_rtl8211f_monitor_work_handler(&data->phy_monitor_work.work);
#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */

/* Advertise default speeds */
phy_rt_rtl8211f_cfg_link(dev, config->default_speeds, 0);

return 0;
}

Expand Down Expand Up @@ -628,6 +632,7 @@ static DEVICE_API(ethphy, rt_rtl8211f_phy_api) = {
static const struct rt_rtl8211f_config rt_rtl8211f_##n##_config = { \
.addr = DT_INST_REG_ADDR(n), \
.mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
RESET_GPIO(n) \
INTERRUPT_GPIO(n) \
}; \
Expand Down
5 changes: 5 additions & 0 deletions drivers/ethernet/phy/phy_ti_dp83825.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct ti_dp83825_config {
uint8_t addr;
const struct device *mdio_dev;
enum dp83825_interface phy_iface;
enum phy_link_speed default_speeds;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
const struct gpio_dt_spec reset_gpio;
#endif
Expand Down Expand Up @@ -537,6 +538,9 @@ static int phy_ti_dp83825_init(const struct device *dev)
phy_ti_dp83825_monitor_work_handler(&data->phy_monitor_work.work);
#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */

/* Advertise default speeds */
phy_ti_dp83825_cfg_link(dev, config->default_speeds, 0);

return 0;
}

Expand Down Expand Up @@ -565,6 +569,7 @@ static DEVICE_API(ethphy, ti_dp83825_phy_api) = {
.addr = DT_INST_REG_ADDR(n), \
.mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
.phy_iface = DT_INST_ENUM_IDX(n, ti_interface_type), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
RESET_GPIO(n) INTERRUPT_GPIO(n)}; \
\
static struct ti_dp83825_data ti_dp83825_##n##_data; \
Expand Down
5 changes: 5 additions & 0 deletions drivers/ethernet/phy/phy_ti_dp83867.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct ti_dp83867_config {
uint32_t ti_rx_internal_delay;
uint32_t ti_tx_internal_delay;
enum dp83826_interface phy_iface;
enum phy_link_speed default_speeds;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
const struct gpio_dt_spec reset_gpio;
#endif
Expand Down Expand Up @@ -575,6 +576,9 @@ static int phy_ti_dp83867_init(const struct device *dev)
#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
phy_ti_dp83867_monitor_work_handler(&data->phy_monitor_work.work);

/* Advertise default speeds */
phy_ti_dp83867_cfg_link(dev, config->default_speeds, 0);

return 0;
}

Expand Down Expand Up @@ -607,6 +611,7 @@ static DEVICE_API(ethphy, ti_dp83867_phy_api) = {
.ti_tx_internal_delay = DT_INST_PROP_OR(n, ti_tx_internal_delay, \
DP83867_RGMII_RX_CLK_DELAY_INV), \
.phy_iface = DT_INST_ENUM_IDX(n, ti_interface_type), \
.default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
RESET_GPIO(n) INTERRUPT_GPIO(n)}; \
\
static struct ti_dp83867_data ti_dp83867_##n##_data; \
Expand Down
2 changes: 1 addition & 1 deletion dts/bindings/ethernet/phy/davicom,dm8806-phy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Davicom DM8806 Ethernet MAC and PHY with RMII interface

compatible: "davicom,dm8806-phy"

include: [ethernet-phy.yaml]
include: [ethernet-phy-common.yaml]

on-bus: mdio

Expand Down
21 changes: 21 additions & 0 deletions dts/bindings/ethernet/phy/ethernet-phy-common.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright The Zephyr Project Contributors
# SPDX-License-Identifier: Apache-2.0

# Common fields for MIIPHY devices

include: phy.yaml

properties:
reg:
required: true
description: PHY address
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"
14 changes: 1 addition & 13 deletions dts/bindings/ethernet/phy/ethernet-phy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ description: Generic MII PHY

compatible: "ethernet-phy"

include: phy.yaml
include: ethernet-phy-common.yaml

properties:
reg:
required: true
description: PHY address
no-reset:
type: boolean
description: Do not reset the PHY during initialization
Expand All @@ -27,14 +24,5 @@ properties:
- "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"]
Loading