Skip to content

Conversation

@mariopaja
Copy link
Contributor

@mariopaja mariopaja commented Aug 13, 2024

This PR adds support for LAN9250 spi ethernet controller.
This driver is tested on the Mikroe ETH Click 3

Console:

[00:00:00.079,000] <inf> eth_lan9250: LAN9250 Initialized
*** Booting Zephyr OS build v3.7.0-565-g2c4498a094de ***
[00:00:00.079,000] <inf> net_dhcpv4_client_sample: Run dhcpv4 client
[00:00:00.079,000] <inf> net_dhcpv4_client_sample: Start on eth_lan9250@0: index=1
[00:00:05.679,000] <inf> net_dhcpv4: Received: 192.168.8.242
[00:00:05.679,000] <inf> net_dhcpv4_client_sample:    Address[1]: 192.168.8.242
[00:00:05.679,000] <inf> net_dhcpv4_client_sample:     Subnet[1]: 255.255.255.0
[00:00:05.679,000] <inf> net_dhcpv4_client_sample:     Router[1]: 192.168.8.1
[00:00:05.679,000] <inf> net_dhcpv4_client_sample: Lease time[1]: 43200 seconds
uart:~$ net iface

Interface eth0 (0x20000e50) (Ethernet) [1]
===================================
Link addr : 80:34:28:01:02:05
MTU       : 1500
Flags     : AUTO_START,IPv4
Device    : eth_lan9250@0 (0x8017248)
Ethernet capabilities supported:
        10 Mbits
        100 Mbits
Ethernet PHY device: <none> (0)
IPv4 unicast addresses (max 1):
        192.168.8.242/255.255.255.0 DHCP preferred
IPv4 multicast addresses (max 2):
        224.0.0.1
IPv4 gateway : 192.168.8.1
DHCPv4 lease time : 43200
DHCPv4 renew time : 21600
DHCPv4 server     : 192.168.8.1
DHCPv4 requested  : 192.168.8.242
DHCPv4 state      : bound
DHCPv4 attempts   : 2
uart:~$ net ping 8.8.8.8
PING 8.8.8.8
28 bytes from 8.8.8.8 to 192.168.8.242: icmp_seq=1 ttl=53 time=30 ms
28 bytes from 8.8.8.8 to 192.168.8.242: icmp_seq=2 ttl=53 time=30 ms
28 bytes from 8.8.8.8 to 192.168.8.242: icmp_seq=3 ttl=53 time=30 ms

Nucleo-H563 Overlay:

&spi1 {
    eth_lan9250: eth_lan9250@0 {
        compatible = "microchip,lan9250";
        spi-max-frequency = <30000000>;
        reg = <0>;
        int-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>;
        status = "okay";
        local-mac-address = [ 80 34 28 01 02 05  ];
    };
};

&mac {
    status = "disabled";
};

&mdio {
    status = "disabled";
};

Test application: lan9250_test_app.zip

Copy link
Member

Choose a reason for hiding this comment

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

There exists WAIT_FOR macro that could perhaps used here and the other wait loops in other functions, could you check if it would make sense to use that here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had a look into it and I tried to implement it. I don't know if I did something wrong but I noticed a performance hit. Receiving an IP took double the time after implementing WAIT_FOR

WAIT_FOR:

[00:00:00.019,000] <inf> eth_lan9250: LAN9250 Initialized
*** Booting Zephyr OS build v3.7.0-945-ga7dd4cb9ce3d ***
[00:00:00.019,000] <inf> net_dhcpv4_client_sample: Run dhcpv4 client
[00:00:00.019,000] <inf> net_dhcpv4_client_sample: Start on eth_lan9250@0: index=1
[00:00:10.669,000] <inf> net_dhcpv4: Received: 192.168.8.242
[00:00:10.669,000] <inf> net_dhcpv4_client_sample:    Address[1]: 192.168.8.242
[00:00:10.669,000] <inf> net_dhcpv4_client_sample:     Subnet[1]: 255.255.255.0
[00:00:10.669,000] <inf> net_dhcpv4_client_sample:     Router[1]: 192.168.8.1
[00:00:10.669,000] <inf> net_dhcpv4_client_sample: Lease time[1]: 43200 seconds
uart:~$ 

while loop:

[00:00:00.074,000] <inf> eth_lan9250: LAN9250 Initialized
*** Booting Zephyr OS build v3.7.0-945-ga7dd4cb9ce3d ***
[00:00:00.074,000] <inf> net_dhcpv4_client_sample: Run dhcpv4 client
[00:00:00.074,000] <inf> net_dhcpv4_client_sample: Start on eth_lan9250@0: index=1
[00:00:05.659,000] <inf> net_dhcpv4: Received: 192.168.8.242
[00:00:05.659,000] <inf> net_dhcpv4_client_sample:    Address[1]: 192.168.8.242
[00:00:05.659,000] <inf> net_dhcpv4_client_sample:     Subnet[1]: 255.255.255.0
[00:00:05.659,000] <inf> net_dhcpv4_client_sample:     Router[1]: 192.168.8.1
[00:00:05.659,000] <inf> net_dhcpv4_client_sample: Lease time[1]: 43200 seconds

Copy link
Member

Choose a reason for hiding this comment

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

This comment line is a bit lonely, perhaps you could add more information what it means (I see it is being used in next line so the comment refers to that)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to give a bit more information this time

Copy link
Member

Choose a reason for hiding this comment

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

indentation is wrong

Copy link
Member

Choose a reason for hiding this comment

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

ditto

Copy link
Member

Choose a reason for hiding this comment

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

and here and other similar lines too, could you check them all

Choose a reason for hiding this comment

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

Please explicitly check the return code (i.e. do not OR the ret)

Choose a reason for hiding this comment

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

My overall impression is that you do use a lot of busy waiting. Is there any special rationale for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is the datasheet that specifies that there are timing rules back to back read-write operations 5.2.1 BACK-TO-BACK WRITE-READ CYCLES, and then I took as a baseline the delays in the ethernet-lan9250 driver.

Choose a reason for hiding this comment

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

You may want to check if CONFIG_NET_BUF_DATA_SIZE is in sync with your setup as you use net_buf_add()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it is needed because it is already checked how much space is available at the end of the buffer with net_buf_tailroom(). Similar to the other SPI Ethernet modules (w5500, enc28j60, eth_enc424j600)

Choose a reason for hiding this comment

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

The LOG_DBG() shall be after declarations

Choose a reason for hiding this comment

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

It looks like you followed the paradigm from LAN8651 (T1S) driver. The rationale for half-duplex transmission there was the issue with driver complexity versus potential gain.

I'm just wondering if the LAN9250 has the opportunity to work full duplex (as other drivers connected via SPI)?

And another question - out of curiosity - have you tested the driver with zperf Zephyr's test program?

Choose a reason for hiding this comment

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

And just to point out - the SPI transmission with chained different buffers was the reason for considerable slow down for STM32 based SoC.

Last but not least - the LAN9250 seems to be 10/100 Mbps - I do assume that it works with 100 Mbps?

Copy link
Contributor Author

@mariopaja mariopaja Aug 14, 2024

Choose a reason for hiding this comment

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

And another question - out of curiosity - have you tested the driver with zperf Zephyr's test program?

No I did not test it, but I can do that too, to test it out.
However, I had a short look on the switch and the device is working at 100Mbps (FE):
lan9250_FE

Last but not least - the LAN9250 seems to be 10/100 Mbps - I do assume that it works with 100 Mbps?

I have enabled auto-negotiation & advertisement capability for both 10/100 Mbps HD/FD

https://github.com/zephyrproject-rtos/zephyr/blob/3b70da4d5f25900cb58f5c8cd89eb6d6f9ec4e77/drivers/ethernet/eth_lan9250.c#L357-L379

Choose a reason for hiding this comment

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

Maybe a bit off-topic. It looks like second MicroClick modules are used as based board. Is there any plan to add them to zephyr as "capes"? IIRC for LAN8651 I also wanted to add it - in a way similar to:
https://github.com/zephyrproject-rtos/zephyr/tree/main/boards/shields/mikroe_wifi_bt_click
or
https://github.com/zephyrproject-rtos/zephyr/tree/main/boards/shields/mikroe_eth_click

but the reply was that we cannot tie to any specific board (like with microe_wifi_bt_click.

Copy link
Contributor Author

@mariopaja mariopaja Aug 14, 2024

Choose a reason for hiding this comment

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

@lmajewski I was also thinking adding it as a shield in a second PR. At the moment I want to pass only a minimal implementation of the driver.

but the reply was that we cannot tie to any specific board (like with microe_wifi_bt_click.

I know that we should not tie drivers to specific shields but also Microship itself is using this module to demonstrate LAN9250 on their Quick Start Guide

@mariopaja mariopaja force-pushed the lan9250 branch 3 times, most recently from 01f1782 to 1d35288 Compare August 17, 2024 15:45
@mariopaja mariopaja marked this pull request as draft August 17, 2024 16:48
@mariopaja
Copy link
Contributor Author

mariopaja commented Aug 17, 2024

Converted to draft because I noticed some unexpected behaviour, while connected to different switches/routers

@mariopaja mariopaja force-pushed the lan9250 branch 3 times, most recently from fd55383 to 117d071 Compare September 1, 2024 14:06
@mariopaja mariopaja marked this pull request as ready for review September 1, 2024 14:32
@mariopaja
Copy link
Contributor Author

@jukkar @lmajewski

Issue mentioned earlier is fixed

[00:00:00.292,000] <inf> eth_lan9250: LAN9250 Initialized
*** Booting Zephyr OS build v3.7.0-945-gfd55383524db ***
[00:00:00.293,000] <inf> net_dhcpv4_client_sample: Run dhcpv4 client
[00:00:00.293,000] <inf> net_dhcpv4_client_sample: Start on eth_lan9250@0: index=1
[00:00:02.895,000] <inf> net_dhcpv4: Received: 192.168.8.240
[00:00:02.896,000] <inf> net_dhcpv4_client_sample:    Address[1]: 192.168.8.240
[00:00:02.896,000] <inf> net_dhcpv4_client_sample:     Subnet[1]: 255.255.255.0
[00:00:02.896,000] <inf> net_dhcpv4_client_sample:     Router[1]: 192.168.8.1
[00:00:02.896,000] <inf> net_dhcpv4_client_sample: Lease time[1]: 43200 seconds
uart:~$ net iface
Hostname: zephyr

Interface eth0 (0x3fc94d60) (Ethernet) [1]
===================================
Link addr : 80:34:28:01:02:03
MTU       : 1500
Flags     : AUTO_START,IPv4
Device    : eth_lan9250@0 (0x3c026bc8)
Ethernet capabilities supported:
        10 Mbits
        100 Mbits
Ethernet PHY device: <none> (0)
IPv4 unicast addresses (max 1):
        192.168.8.240/255.255.255.0 DHCP preferred
IPv4 multicast addresses (max 2):
        224.0.0.1
IPv4 gateway : 192.168.8.1
DHCPv4 lease time : 43200
DHCPv4 renew time : 21600
DHCPv4 server     : 192.168.8.1
DHCPv4 requested  : 192.168.8.240
DHCPv4 state      : bound
DHCPv4 attempts   : 1
uart:~$ net ping 8.8.8.8
PING 8.8.8.8
28 bytes from 8.8.8.8 to 192.168.8.240: icmp_seq=1 ttl=111 time=68 ms
28 bytes from 8.8.8.8 to 192.168.8.240: icmp_seq=2 ttl=111 time=64 ms
28 bytes from 8.8.8.8 to 192.168.8.240: icmp_seq=3 ttl=111 time=64 ms
uart:~$ 

xiao esp32s3 overlay:

&spi2 {
    cs-gpios=<&gpio0 3 GPIO_ACTIVE_LOW>;
    eth_lan9250: eth_lan9250@0 {
        compatible = "microchip,lan9250";
        spi-max-frequency = <60000000>;
        reg = <0>; 
        int-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>; 
        status = "okay";
        local-mac-address = [80 34 28 01 02 03];
    };
};

This was the best performance I could get:
Screenshot 2024-09-01 at 10 24 37

@albertofloyd albertofloyd removed their request for review September 20, 2024 20:50
@mariopaja mariopaja requested review from jukkar and lmajewski October 2, 2024 06:48
Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

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

Some very minor style nits from me, other than that looks reasonable.

@mariopaja mariopaja force-pushed the lan9250 branch 3 times, most recently from bc1038c to edcbb6e Compare October 4, 2024 17:15
@mariopaja
Copy link
Contributor Author

mariopaja commented Nov 26, 2024

@auroramisic I noticed that restarting the board after flashing helps of fix the SPI communication issue

BTW this is only a basic implementation of this SPI Ethernet Controller and many features are still missing

I disabled the following to be able to read the log better

#CONFIG_ETHERNET_LOG_LEVEL_DBG=y
#CONFIG_NET_L2_ETHERNET_LOG_LEVEL_DBG=y
#CONFIG_NET_CONFIG_LOG_LEVEL_DBG=y
#CONFIG_NET_IF_LOG_LEVEL_DBG=y
Screenshot 2024-11-26 at 15 37 42

LOG:

[00:00:00.356,872] <inf> eth_lan9250: LAN9250 Initialized
*** Booting Zephyr OS build (tainted) v3.7.0-5314-g0af29b47bbe5 ***
[00:00:00.358,642] <inf> net_config: Initializing network
[00:00:00.358,642] <inf> net_config: Waiting interface 1 (0x200019c8) to be up...
[00:00:01.763,061] <inf> net_config: Interface 1 (0x200019c8) coming up
[00:00:01.763,183] <inf> net_config: IPv4 address: 192.168.1.115
uart:~$ Failed to connect to server
net iface
Hostname: zephyr


Interface eth0 (0x200019c8) (Ethernet) [1]
===================================
Link addr : 80:34:28:01:02:03
MTU       : 1500
Flags     : AUTO_START,IPv4,IPv6
Device    : eth_lan9250@0 (0x4ec2c)
Ethernet capabilities supported:
        10 Mbits
        100 Mbits
Ethernet PHY device: <none> (0)
IPv6 unicast addresses (max 2):
        fe80::8234:28ff:fe01:203 autoconf preferred infinite
IPv6 multicast addresses (max 3):
        ff02::1
        ff02::1:ff01:203
IPv6 prefixes (max 2):
        <none>
IPv6 hop limit           : 64
IPv6 base reachable time : 30000
IPv6 reachable time      : 29987
IPv6 retransmit timer    : 0
IPv4 unicast addresses (max 1):
        192.168.1.115/255.255.255.0 manual preferred infinite
IPv4 multicast addresses (max 2):
        224.0.0.1
IPv4 gateway : 192.168.1.1
uart:~$ net ping 8.8.8.8
PING 8.8.8.8
28 bytes from 8.8.8.8 to 192.168.1.115: icmp_seq=1 ttl=112 time=70 ms
28 bytes from 8.8.8.8 to 192.168.1.115: icmp_seq=2 ttl=112 time=63 ms
28 bytes from 8.8.8.8 to 192.168.1.115: icmp_seq=3 ttl=112 time=69 ms
uart:~$ 

@auroramisic
Copy link

@mariopaja restarting the dk did not fix the issue. And the log is still the same

@mariopaja
Copy link
Contributor Author

mariopaja commented Nov 26, 2024

@mariopaja restarting the dk did not fix the issue. And the log is still the same

@auroramisic

I could replicate the issue, and it was SPI communication error.
Unfortunately, I can't help you further because I don't have that board.

If you are using the nrf52840dk_nrf52840, please check the overlay you are using.

The following overlay which is included with the provided sample:

&pinctrl {
    spi2_default: spi2_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 04)>,
                <NRF_PSEL(SPIM_MISO, 0, 30)>,
                <NRF_PSEL(SPIM_MOSI, 0, 31)>;
        };
    };
};

does not match nrf52840dk_nrf52840-pinctrl.dtsi

	spi2_default: spi2_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 19)>,
				<NRF_PSEL(SPIM_MOSI, 0, 20)>,
				<NRF_PSEL(SPIM_MISO, 0, 21)>;
		};
	};

	spi2_sleep: spi2_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 19)>,
				<NRF_PSEL(SPIM_MOSI, 0, 20)>,
				<NRF_PSEL(SPIM_MISO, 0, 21)>;
			low-power-enable;
		};
	};

@mariopaja
Copy link
Contributor Author

@pdgendt @jukkar rebased to solve merge issues

@mariopaja mariopaja force-pushed the lan9250 branch 2 times, most recently from b962452 to e314c2c Compare December 8, 2024 15:04
@mariopaja mariopaja force-pushed the lan9250 branch 2 times, most recently from a308018 to 85ab349 Compare December 8, 2024 15:35
This PR adds support for LAN9250 spi ethernet controller.
This driver is tested on the Mikroe ETH Click 3
https://www.mikroe.com/eth-3-click

Signed-off-by: Mario Paja <[email protected]>
Add build test for microchip lan9250

Signed-off-by: Mario Paja <[email protected]>
@kartben kartben merged commit 03b936f into zephyrproject-rtos:main Dec 10, 2024
25 checks passed
@kartben
Copy link
Contributor

kartben commented Dec 10, 2024

This driver is tested on the Mikroe ETH Click 3

@mariopaja please contribute a new shield definition for it when you have a chance :)

@mariopaja
Copy link
Contributor Author

@mariopaja please contribute a new shield definition for it when you have a chance :)

@kartben I will do it soon :)

@auroramisic
Copy link

@mariopaja If someone has the same issue with nordic in the future, the fix for the system was to add nordic,drive-mode = <NRF_DRIVE_H0H1>; to the overlay file. So, that the overlay file becomes this:

&spi2 {
    cs-gpios=<&gpio0 28 GPIO_ACTIVE_LOW>;
    status = "okay";
    eth_lan9250: eth_lan9250@0 {
        compatible = "microchip,lan9250";
        spi-max-frequency = <1000000>;
        reg = <0>; 
        int-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; 
        status = "okay";
        local-mac-address = [80 34 28 01 02 03];
    };
};

&pinctrl {
    spi2_default: spi2_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 04)>,
                <NRF_PSEL(SPIM_MISO, 0, 30)>,
                <NRF_PSEL(SPIM_MOSI, 0, 31)>;
            nordic,drive-mode = <NRF_DRIVE_H0H1>;    
        };
    };
};

&pinctrl {
    spi2_sleep: spi2_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 04)>,
                <NRF_PSEL(SPIM_MISO, 0, 30)>,
                <NRF_PSEL(SPIM_MOSI, 0, 31)>;
        };
    };
};

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.