Post Go back to editing

ADIN2110 with Linux driver can't send/receive

Category: Software

I am looking for some help getting the adin2111 driver working on my imx8mm based board. 

I am at a point where I see the interfaces after boot. They both have the some HWaddr, which is a problem I think I need to solve, but in the meantime can change the HWaddr of one of the interfaces manually.

I am using the EVAL-ADIN1100 as a media converter and I have the 10BASE-T1L side connect to my board, and the Ethernet side connect to a PC with a manually IP address set to 10.10.10.200. Both link lights are lit on the EVAL-ADIN1100. I even see the occasional blink indicating activity on the EVAL-ADIN1100 and on my board.

If I set an IP address 10.10.10.2 on eth1 and try to ping 10.10.10.200 I get no response, no link activity and no traffic detected on Wireshark running on the PC.

If I ping from the PC, don't get a response, but on my board something strange happens.

 

I notice using top that irq/78 (irq assigned to the adin2111 chip) is consuming 30% CPU and if I check the interrupt line with a scope I see activity but the interrupt is spending most of it's time low. So the driver is actively trying to read from the adin2111 but is unable to clear the interrupt.

So it seems I can't send packets from the board, and if I try to send packets to the board, the interrupt gets stuck and I receive no traffic.

I've tried to load the driver as a module, thinking starting it up after boot might help, but it did not.

I've looked the configuration of the SPI_CFG0 and SPI_CFG1 thinking spi might have be accidently configured as open alliance, but it looks like it's configured as generic spi.

I've kept spi speed low for now to make sure that isn't causing a problem.

I've verified the reset gpio is correctly resetting the chip during probe.

Does anyone have suggestions on what might be wrong, or what I can try next to troubleshoot?

Here is my device tree 

&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi2>;
cs-gpios = <0>;
status = "okay";

ethernet@0 {
compatible = "adi,adin2111";
pinctrl-1 = <&pinctrl_spe>;

/* SPI CS number */
reg = <0>;

reset-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;

/* will need 23 MHz for 10 Mbps, lower speeds will result in lower bandwidth */
spi-max-frequency = <1000000>;

/* optional, will check all control read/writes over SPI */
adi,spi-crc;

#address-cells = <1>;
#size-cells = <0>;

/* an IRQ is required, INT_N pin is configured to signal RX/TX frames */
interrupt-parent = <&gpio1>;
interrupts = <14 IRQ_TYPE_LEVEL_LOW>;

/* This is the host MAC address, by default ADIN2111 will also accept broadcast frames */
mac-address = [ CA 2F B7 10 23 63 ];

phy@0 {
compatible = "ethernet-phy-id0283.bca1";
reg = <0x0>;
};

phy@1 {
compatible = "ethernet-phy-id0283.bca1";
reg = <0x1>;
};
};
};

&iomuxc {
/*spi to the ADIN2111*/
pinctrl_ecspi2: ecspi2grp {
fsl,pins = <
MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x10
MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x90
MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x90
MX8MM_IOMUXC_ECSPI2_SS0_ECSPI2_SS0 0x90
>;
};

pinctrl_spe: spegrp {
fsl,pins = <
/* spe int */
MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x90
>;
};
};

  • Best approach now, would probably be to debug the driver a bit.

    Maybe set some "pr_err("%s %d\n", __func__, __LINE__);" prints in the adin1110_irq() routine and see what happens, and where it goes.

    Hopefully the reading of the status regs works fine.

    Maybe print the values of the status0 & status1 regs; maybe this "adin1110_write_reg(priv, ADIN1110_STATUS1, priv->irq_mask);" ?

    Maybe it's getting some interrupts it is not clearing? Who knows?



    At this point, I'm thinking that the SPI communication should be fine (since it probed).
    The driver is using SPI MODE0 (by default).
    If the driver probes fine, I would think that the mode is fine (on the HW side as well).
    But, SPI can cause surprises sometimes. So, maybe make sure that SPI mode is 0 on the SPI controller?


    Cheers
    Alex

  • Hi  Can your team please have a look at this?

    Regards,

    Raquel.

  • Thanks for responses!

    I have an update. I am actually backporting the recent driver into an earlier kernel version (linux-imx v5.15). I added the ADIN1110/2111 driver but realized I was missing the AD1100 phy driver. Maybe this would explain why I couldn't actually send/receive anything sensible. After I added the AD1100 driver I now get a different problem.

    Add boot, I am seeing an problem with the phy setup which I've pasted below.

    [ 12.162910] ADIN1100 spi1.0:01: adin_set_powerdown_mode failed: -110
    [ 12.164411] ADIN1100 spi1.0:02: adin_set_powerdown_mode failed: -110

    I wonder if I've missed anything else... 

    Do I really need the ADI1100 driver or is all the phy communication handled by the AD2111?

    Btw, I'm following instruction from ADIN2111 10BASE-T1L SWITCH Linux Driver Quick Start [Analog Devices Wiki] and ADIN2111 10BASE-T1L 2-Port Ethernet Switch Linux Driver [Analog Devices Wiki]

  • Maybe it helps describing your physical setup.
    What boards are being used and how they're connected.

    At least, I am a bit fuzzy on what and how is in the setup chain.
    I saw some EVAL-ADIN1100, but there's mention of the ADIN2111.

    Is there a possibility to see a picture of the setup? With wirings and board models?

  • Sure here is a picture of the setup. Hope it helps. The eval board is Eval-ADIN1100EBZ - it's set up in media converter mode

    .

  • Who//what is driving the  EVAL-ADIN1100  ?

    I wonder if it works as a media-converter by-default like that without some register configuration.

    Does the ADIN1100 PHY have all the proper clock signals?
    Usually between MAC and PHYs, there's some clock signals that need to be interlinked so that the data can flow.
    Often, the MAC can supply the clocks, or it can be a separate clock-signal on the board.

  • My bad.

    EVAL-ADIN1100 works as a standalone media converter.

    Apologies for the confusion.

    Next question would be: where are you picking the driver from? (Which git tree).

    Would it be possible to see a branch on Github (or similar) with just the the imx8 kernel + the ADIN2111 driver port?

    If it’s a Linux problem, it can be easier to see like that.

  • Hi  ,

    Besides the already suggested debug messages in adin1110_irq(), I think it would also be worth checking the error counter registers (0xAD - P1_RX_DROP_FILT_CNT for example, there are several others for IFG, long/short errors), while you ping your board from the PC. This might help ruling out hardware issues.

    Thanks,

    Ciprian

  • I don't have a branch I can share, but I can show you changes to the ported ADIN1110 driver. 

    I started with the latest stable version 6.5.7 at kernel.org, which is on the right.

    There are two small changes in the ported version:

    The AD1100 driver is also from 6.5.7. and is unchanged.

  • Now that I've switched to using the ADIN1100 phy driver I am seeing different behavior than I originally described.  I don't see the link lights as I initially did when I didn't include the ADIN1100 phy driver.

    I am pretty sure the ADIN1100 phy driver is needed to communicate with the ADIN1100 phys internal to the ADIN2111. This is stated in ADIN2111 10BASE-T1L SWITCH Linux Driver Quick Start [Analog Devices Wiki] as "Enable ADIN1100 and ADIN1110 from the make menuconfig. Note: ADIN2111 is supported by the adin1110.c Linux driver."

    In ethtool I see 

    cxchp2:/home/root # ethtool eth1
    Settings for eth1:
    Supported ports: [ TP MII ]
    Supported link modes: Not reported
    Supported pause frame use: Symmetric Receive-only
    Supports auto-negotiation: No
    Supported FEC modes: Not reported
    Advertised link modes: Not reported
    Advertised pause frame use: No
    Advertised auto-negotiation: No
    Advertised FEC modes: Not reported
    Speed: Unknown!
    Duplex: Unknown! (255)
    Auto-negotiation: off
    Port: Twisted Pair
    PHYAD: 1
    Transceiver: external
    MDI-X: Unknown
    Link detected: no
    SQI: 0/7
    cxchp2:/home/root #

    When I debug the auto-negotiation function adin_config_aneg() in an1100.c, the first return is hit as auto-negotiation is disabled. It is supposed to be enabled by default.

    static int adin_config_aneg(struct phy_device *phydev)
    {
        struct adin_priv *priv = phydev->priv;
        int ret;
        if (phydev->autoneg == AUTONEG_DISABLE) {
            ret = genphy_c45_pma_setup_forced(phydev);
            if (ret < 0)
                return ret;

    I am sure the SPI port is working as the ADIN2111 is probed ok.

    I'll continue to debug and try to figure out why the ADIN1100 phy does not appear to be configured as expected. Perhaps  device tree problem - though I am using the device tree example at the link above.

    If you have additional suggestions on where I can look/debug, please let me know.

    Thanks!