From 80787c4e5ac1f6a20602b1b251a4904ba1c38bc8 Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Sat, 8 Nov 2025 11:25:09 -0800 Subject: [PATCH 1/2] drivers: ethernet: lan9250: add support for a random mac address Extend the lan9250 driver to support using a local administered unicast random mac address during init. This follows the device tree settings for zephyr_random_mac_address from other ethernet drivers for the added support. Signed-off-by: Charles Hardin --- drivers/ethernet/eth_lan9250.c | 3 +++ drivers/ethernet/eth_lan9250_priv.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 9aac0052d220a..895ee61222b81 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -697,6 +697,8 @@ static int lan9250_init(const struct device *dev) return ret; } lan9250_configure(dev); + + (void)net_eth_mac_load(&config->mac_cfg, context->mac_address); lan9250_set_macaddr(dev); k_thread_create(&context->thread, context->thread_stack, @@ -719,6 +721,7 @@ static int lan9250_init(const struct device *dev) .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8)), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .timeout = CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT, \ + .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(inst), \ }; \ \ ETH_NET_DEVICE_DT_INST_DEFINE(inst, lan9250_init, NULL, &lan9250_##inst##_runtime, \ diff --git a/drivers/ethernet/eth_lan9250_priv.h b/drivers/ethernet/eth_lan9250_priv.h index b6379216bdf3e..8e755c0239b95 100644 --- a/drivers/ethernet/eth_lan9250_priv.h +++ b/drivers/ethernet/eth_lan9250_priv.h @@ -312,6 +312,7 @@ struct lan9250_config { struct gpio_dt_spec reset; uint8_t full_duplex; int32_t timeout; + struct net_eth_mac_config mac_cfg; }; struct lan9250_runtime { From d26c4b73c6c92ce5593b6e8ce2747c6148f29c21 Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Sat, 8 Nov 2025 11:37:46 -0800 Subject: [PATCH 2/2] drivers: ethernet: lan9250: add in the reset gpio configurate The reset gpio field was in the config structure but was not coded into the initialization path. So, add the appropriate code to handle the gpio setup when it is defined in the device tree. Signed-off-by: Charles Hardin --- drivers/ethernet/eth_lan9250.c | 45 +++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 895ee61222b81..339cf794ad93c 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -678,17 +678,49 @@ static int lan9250_init(const struct device *dev) return -EINVAL; } - if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) { + ret = gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT); + if (ret < 0) { LOG_ERR("Unable to configure GPIO pin %u", config->interrupt.pin); - return -EINVAL; + return ret; } - gpio_init_callback(&(context->gpio_cb), lan9250_gpio_callback, BIT(config->interrupt.pin)); - if (gpio_add_callback(config->interrupt.port, &(context->gpio_cb))) { - return -EINVAL; + gpio_init_callback(&(context->gpio_cb), lan9250_gpio_callback, + BIT(config->interrupt.pin)); + ret = gpio_add_callback(config->interrupt.port, &context->gpio_cb); + if (ret < 0) { + LOG_ERR("Unable to add GPIO callback %u", config->interrupt.pin); + return ret; } - gpio_pin_interrupt_configure_dt(&config->interrupt, GPIO_INT_EDGE_TO_ACTIVE); + ret = gpio_pin_interrupt_configure_dt(&config->interrupt, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("Unable to enable GPIO INT %u", config->interrupt.pin); + return ret; + } + + if (config->reset.port != NULL) { + if (!gpio_is_ready_dt(&config->reset)) { + LOG_ERR("GPIO port %s not ready", config->reset.port->name); + return -EINVAL; + } + + ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Unable to configure GPIO pin %u", config->reset.pin); + return ret; + } + + /* See Section 19.6.3 from the LAN9250 Data Sheet + * + * trstia is 200 microseconds min (use 250 us) + * tcfg is 15 milliseconds min (use 20 ms for after reset) + */ + gpio_pin_set_dt(&config->reset, 1); + k_usleep(250); + gpio_pin_set_dt(&config->reset, 0); + k_msleep(20); + } /* Reset and wait for ready on the LAN9250 SPI device */ ret = lan9250_sw_reset(dev); @@ -720,6 +752,7 @@ static int lan9250_init(const struct device *dev) static const struct lan9250_config lan9250_##inst##_config = { \ .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8)), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \ .timeout = CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT, \ .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(inst), \ }; \