Device tree configuration for Imx8M Nano with Ksz9893 ethernet switch

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Device tree configuration for Imx8M Nano with Ksz9893 ethernet switch

5,332 Views
Jamier
Contributor III

I am looking for some help with getting ethernet working through a KSZ9893 switch. The switch is set up talking RGMII to the FEC controller in the imx8mn and there are two ports on the switch.

I am able to see the interfaces in Linux.  I set the HWaddr manually, and assigned static IPs.

I can talk to the switch via i2c from uboot and can verify configuration looks right for RMGII mode, speed.

As far as I can tell everything looks good. But obviously I must be missing something:

Ping gets no response in either direction for lan1 and lan2dhcli.

 

Anyone have some insight?

Thanks!

Boot messages show:

[ 5.215194] Generic PHY fixed-0:00: attached PHY driver [Generic PHY] (mii_bus:phy_addr=fixed-0:00, irq=POLL)
[ 5.227720] fec 30be0000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
[ 5.242708] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 5.877300] device eth0 entered promiscuous mode
[ 5.908209] ksz9477-switch 2-005f lan1: configuring for phy/gmii link mode
[ 5.920966] 8021q: adding VLAN 0 to HW filter on device lan1
[ 6.009992] ksz9477-switch 2-005f lan2: configuring for phy/gmii link mode
[ 6.023374] 8021q: adding VLAN 0 to HW filter on device lan2
[ 6.029934] ksz9477-switch 2-005f lan2: Link is Up - 100Mbps/Full - flow control rx/tx
[ 6.059149] IPv6: ADDRCONF(NETDEV_CHANGE): lan2: link becomes ready
[ 6.953814] ksz9477-switch 2-005f lan1: Link is Up - 1Gbps/Full - flow control off
[ 6.961495] IPv6: ADDRCONF(NETDEV_CHANGE): lan1: link becomes ready

ifconfig output:

eth0 Link encap:Ethernet HWaddr 26:cf:fb:16:d7:a4
inet6 addr: fe80::577e:e7b9:1b18:c87d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:407 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:69240 (67.6 KiB)

lan1 Link encap:Ethernet HWaddr 26:cf:fb:16:d7:a6
inet addr:10.10.10.3 Bcast:10.10.10.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:2615 (2.5 KiB)

lan2 Link encap:Ethernet HWaddr 26:cf:fb:16:d7:a5
inet addr:10.10.10.4 Bcast:10.10.10.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:319 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:52744 (51.5 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:3414 errors:0 dropped:0 overruns:0 frame:0
TX packets:3414 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:213404 (208.4 KiB) TX bytes:213404 (208.4 KiB)


Device Tree nodes:

&i2c3 {
clock-frequency = <100000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
pinctrl-1 = <&pinctrl_i2c3_gpio>;
scl-gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
sda-gpios = <&gpio5 19 GPIO_ACTIVE_HIGH>;
status = "okay";

ksz9893: ksz9893@5f {
compatible = "microchip,ksz9893";
reg = <0x5f>;

status = "okay";

ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan1";
local-mac-address = [26 cf fb 16 d7 a4];
};
port@1 {
reg = <1>;
label = "lan2";
local-mac-address = [26 cf fb 16 d7 a5];
};
port@2 {
reg = <2>;
label = "cpu";
ethernet = <&fec1>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
};

&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
status = "okay";
clocks = <&clk IMX8MN_CLK_ENET1_ROOT>,
<&clk IMX8MN_CLK_ENET1_ROOT>,
<&clk IMX8MN_CLK_ENET_TIMER>,
<&clk IMX8MN_CLK_ENET_REF>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref";

/delete-property/ stop-mode;

fixed-link {
speed = <1000>;
full-duplex;
};


};

 

 

 

 

0 Kudos
Reply
6 Replies

3,148 Views
gaurav_bankar
Contributor II

Hello @Jamier,

   I am using a similar switch to ksz9893 that it ksz9563. I have done all the necessary things mentioned in this thread. The issue I am facing is that my lan1 and lan2 link are not up after boot. I have to explicitly make them up by giving command ip link set lan1 up. 

I tried adding them in /etc/network/interfaces but that didnt work. 

Did you used some script to up them? 

0 Kudos
Reply

5,319 Views
Jamier
Contributor III

Thanks for the help. 

Turns out the driver wasn't setting the ingress delay as expected. Once I turned on both ingress and egress delay on the switch, ping started to work.

4,599 Views
Alex2022
Contributor II

Hello @Jamier,

I am exactly on the same point, KSZ9893 driver seems to work, but ping does not. Could you please explain how did you turn on egress and ingress delays on the switch?

What registers did you write and with which values?

Thank you in advance for your help.

Alex

0 Kudos
Reply

4,592 Views
Jamier
Contributor III

Hi Alex,

I managed to dig up the patch I made to turn on the delays. Here is a snippet from the patch file:

You'll need to set phy-mode in your device tree something like this:

@@ -451,6 +451,7 @@
reg = <2>;
label = "cpu";
ethernet = <&fec1>;
+ phy-mode = "rgmii-id";
fixed-link {
speed = <1000>;
full-duplex;

Then set the PORT_RGMII_ID_IG_ENABLE and PORT_RGMII_ED_IG_ENABLE bits on the REG_PORT_XMII_CTRL_1 register. Patch snippet below.

diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index d9c54ea7a4b6..9723143514a1 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c

@@ -1260,6 +1264,13 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
if (dev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
dev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
data8 |= PORT_RGMII_ID_EG_ENABLE;
+
+ /*Force enable the delays for our SOM. The above code to set them depending on
+ the interface doesn't seem to work through device tree. It just reads the bits
+ in the register as they are.*/
+ data8 |= PORT_RGMII_ID_IG_ENABLE;
+ data8 |= PORT_RGMII_ID_EG_ENABLE;
+
/* On KSZ9893, disable RGMII in-band status support */
if (dev->features & IS_9893)
data8 &= ~PORT_MII_MAC_MODE;

Based on the comment I made I am not totally comfortable with this approach - I don't understand why this was necessary, since the existing code should have been setting the bits based on device tree parameters. When I did this my understanding of device tress and kernel drivers was in it's infancy so I likely made an error somewhere and to compensate and forced the bits regardless of device tree.

4,583 Views
Alex2022
Contributor II

Thank you @Jamier, after editing the device tree and recompiling it worked, I did not need to edit the KSZ9477 driver.

Thanks again for your help.

Alex

0 Kudos
Reply