From b40fb049f5bff177176dc600d3965bb017e83c54 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 | 10 ++++++++++ drivers/ethernet/eth_lan9250_priv.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index f16e2eaac94e1..bcb519de61928 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "eth_lan9250_priv.h" @@ -697,6 +698,14 @@ static int lan9250_init(const struct device *dev) return ret; } lan9250_configure(dev); + + /* use a random MAC address if requested in the device tree */ + if (config->random_mac) { + sys_rand_get(context->mac_address, sizeof(context->mac_address)); + /* locally administered, unicast address */ + context->mac_address[0] &= ~(BIT(0) | BIT(2) | BIT(3)); + context->mac_address[0] |= BIT(1); + } lan9250_set_macaddr(dev); k_thread_create(&context->thread, context->thread_stack, @@ -719,6 +728,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, \ + .random_mac = DT_INST_PROP(inst, zephyr_random_mac_address), \ }; \ \ 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..58668853ebe09 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; + bool random_mac; }; struct lan9250_runtime { From 1c940f77ea26fa5334a67fa13ec0ef684ba1f768 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 | 44 +++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index bcb519de61928..7e80df6d627e9 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -679,17 +679,48 @@ 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) { + 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); + 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); @@ -727,6 +758,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, \ .random_mac = DT_INST_PROP(inst, zephyr_random_mac_address), \ }; \