Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

uClinux nommu does not detect PHY in SGMII mode

I have a 4sgx230 board and have been trying to get uClinux up on it. I have finally gotten it but I have a problem where the PHY is not detected. I am using TSE and the PHY is Marvel 88E1111. The board can only be used in SGMII mode since the other signals are not connected. I get this error at boot time:

....

....

console [ttyJ0] enabled

ttyS0 at MMIO 0x8004c80 (irq = 10) is a Altera UART

atse driver failed to detect an ether phy:/usr/src/nios2-linux/linux-2.6/drivers/net/atse.c:1455:atse_probe()

TCP cubic registered

NET: Registered protocol family 17

....

....

I can go in the sopc_builder and change it to use MII/GMII and get it to detect the phy, but I know it will not work since the hardware is not present, first indication being that soft reset of the TSE never returns (SW reset bit ATSE_MAC_CC_SW_RESET_BIT gets stuck).

.....

.....

eth0: atse.c: v1.1, June 3, 2008 by Joseph (Camel) Chen <joe4camel@gmail.com>

eth0: atse.c: modified version by Eintisy Chuang <eintisy.chuang@gfec.com.tw>

eth0: altera tripple speed, ether hw addr 00:07:ed:0d:09:19, marvell 88e1111 phy

.....

.....

/> dhcpcd eth0

ATSE: Waiting on PHY link ......

atse driver:/usr/src/nios2-linux/linux-2.6/drivers/net/atse.c:530:mac sw reset bit never cleared!

eth0 up, link speed 1000, full duplex, eth hw addr 00:07:ed:0d:09:19

dhcpcd[26]: timed out waiting for a valid DHCP seth0 down

erver response

Anyone seen it before, I am about to jump into the code, but am hoping someone has already done that.

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It seems to be already in SGMII mode, (if_mode_register == 0x03)

    I just started looking into code, ill probably get it done soon
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I guess the code is using the wrong set of registers for detecting the PHY, it works fine (tested with ping, dhcp, etc) if I use the second set. I changed the detection code:

    from:

    for (phy_addr = 0x0; phy_addr < 0xFF; phy_addr++) {

    /* set the phy address to the mac map data */

    writel(phy_addr, ATSE_MAC_REG_MDIO_ADDR_0);

    phy_id_1 = readl(ATSE_MAC_REG_MDIO_SPACE_0 + ATSE_PHY_ID_1_OFFSET);

    phy_id_2 = readl(ATSE_MAC_REG_MDIO_SPACE_0 + ATSE_PHY_ID_2_OFFSET);

    if (phy_id_1 != phy_id_2) {

    found_phy = 1;

    break;

    }

    To:

    for (phy_addr = 0x0; phy_addr < 0xFF; phy_addr++) {

    /* set the phy address to the mac map data */

    writel(phy_addr, ATSE_MAC_REG_MDIO_ADDR_1);

    phy_id_1 = readl(ATSE_MAC_REG_MDIO_SPACE_1 + ATSE_PHY_ID_1_OFFSET);

    phy_id_2 = readl(ATSE_MAC_REG_MDIO_SPACE_1 + ATSE_PHY_ID_2_OFFSET);

    if (phy_id_1 != phy_id_2) {

    found_phy = 1;

    break;

    }

    Ill go through the TSE docs again and create the right patch so it works in all modes.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem is that the current atse driver (besides many other assumptions) assumes that we will never use PCS mode. Here is the patch that should fix this problem. To compile it define USE_PCS_MODE. Ill try to submit it.

     
    diff -uNr nios2-linux.vanilla/linux-2.6/drivers/net/atse.h nios2-linux/linux-2.6/drivers/net/atse.h
    --- nios2-linux.vanilla/linux-2.6/drivers/net/atse.h    2010-06-02 15:42:18.000000000 -0500
    +++ nios2-linux/linux-2.6/drivers/net/atse.h    2010-06-29 14:32:24.000000000 -0500
    @@ -72,10 +72,18 @@
     /* number of bytes in one MDIO register */
    # define ATSE_PHY_ID_1_OFFSET   (2 * BYTES_IN_WORD)
    # define ATSE_PHY_ID_2_OFFSET   (3 * BYTES_IN_WORD)
    +
    +#ifdef USE_PCS_MODE
    +#define ATSE_MAC_REG_MDIO_ADDR_1   (ATSE_MAC_BASE + 0x3C  )
    +#define ATSE_MAC_REG_MDIO_ADDR_0   (ATSE_MAC_BASE + 0x40  )
    +#define ATSE_MAC_REG_PCS_0  (ATSE_MAC_BASE + 0x0200)
    +#define ATSE_MAC_REG_MDIO_SPACE_0  (ATSE_MAC_BASE + 0x0280)
    +#else
    # define ATSE_MAC_REG_MDIO_ADDR_0   (ATSE_MAC_BASE + 0x3C  )
    # define ATSE_MAC_REG_MDIO_ADDR_1   (ATSE_MAC_BASE + 0x40  )
    # define ATSE_MAC_REG_MDIO_SPACE_0  (ATSE_MAC_BASE + 0x0200)
    # define ATSE_MAC_REG_MDIO_SPACE_1  (ATSE_MAC_BASE + 0x0280)
    +#endif
    # define ATSE_SET_PHY_MDIO_CONTROL(n) writel((n), ATSE_MAC_REG_MDIO_SPACE_0)
    # define ATSE_GET_PHY_MDIO_CONTROL()  readl(ATSE_MAC_REG_MDIO_SPACE_0)
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    My impression is that the altera_tse (not atse) is the one that is written better. Though I haven't done a comparison, on first glance (a little over a year ago), altera_tse was the better driver...

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I was not even able to get a peep out of that one (should have looked at it too), but now that I look at the source, you are correct. It is definitely better and worth looking. Ill take a look.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, is there anyone get the altera_tse.c working on stratix iv GX FPGA development kit borad? Thanks.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    I'm also trying to get a 4SGX230 to talk to the 88E111 over SGMII. However, I cannot even compile the current atse.h/c driver because of:

    #ifndef na_tse_mac_control_port
    # error "**** This build has not been configured with Alteras example design of TSE-SGDMA."
    # error "**** You need to do: make vendor_hwselect SYSPTF=<your_path>/NiosII_stratixII_2s60_RoHS_TSE_SGDMA_sopc.ptf"
    # error "**** Or, You need to unselect ATSE ethernet driver with make menuconfig"
    # endif
    

    Which "make vendor_hwselect" isn't used / doesn't work anymore, so it's way out of date.

    Using altera_tse.c/h doesn't seem to work for me. Negotiation fails and the kernel outputs:

    Trying 10/HALF

    I've tried specifying the SGMII mode in the atl_tse_config struct, but nothing seems to work:

    static struct alt_tse_config tsemac0_config = {
        .mii_id = 0,
        .phy_addr = 0,
        .tse_supported_modes =  PHY_GBIT_FEATURES,
    /*
        supported modes can be
            SUPPORTED_10baseT_Half
            SUPPORTED_10baseT_Full
            SUPPORTED_100baseT_Half
            SUPPORTED_100baseT_Full
            SUPPORTED_Autoneg
            SUPPORTED_TP
            SUPPORTED_MII  ----------  Up to here is PHY_BASIC_FEATURES
            SUPPORTED_1000baseT_Half
            SUPPORTED_1000baseT_Full -- here PHY_GBIT_FEATURES
    */
        .interface = PHY_INTERFACE_MODE_SGMII,
    /*  Interfaces can be
            PHY_INTERFACE_MODE_MII
            PHY_INTERFACE_MODE_GMII
            PHY_INTERFACE_MODE_SGMII
            PHY_INTERFACE_MODE_TBI
            PHY_INTERFACE_MODE_RMII
            PHY_INTERFACE_MODE_RGMII
            PHY_INTERFACE_MODE_RGMII_ID
            PHY_INTERFACE_MODE_RGMII_RXID
            PHY_INTERFACE_MODE_RGMII_TXID
            PHY_INTERFACE_MODE_RTBI
    */
        .flags = 0,  /* these are apparently phy specific... */
        .autoneg = AUTONEG_ENABLE,
        /* speed and duplex only valid if autoneg is AUTONED_DISABLE */
        .speed = SPEED_100, /* SPEED_10, SPEED_100, SPEED_1000 */
        .duplex = DUPLEX_HALF, /* DUPLEX_HALF, DUPLEX_FULL */
        .rx_fifo_depth = ALT_TSE_TX_RX_FIFO_DEPTH,
        .tx_fifo_depth = ALT_TSE_TX_RX_FIFO_DEPTH,
        .ethaddr = {0x00 , 0x70 , 0xed , 0x11 , 0x12 , 0x12},
    };
    

    Is there an updated atse driver? I've updated my local git repository, but the log for the atse.h shows it was last touched in 2008.

    Edit:

    Ethtool output:

    root:/> ethtool eth0
    Settings for eth0:
            Supported ports: 
            Supported link modes:   
            Supports auto-negotiation: Yes
            Advertised link modes:  Not reported
            Advertised auto-negotiation: Yes
            Speed: 1000Mb/s
            Duplex: Full
            Port: MII
            PHYAD: 0
            Transceiver: external
            Auto-negotiation: off
            Current message level: 0x00000000 (0)
            Link detected: yes
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The same kind of hack for using PCS works for the altera_tse.c drivers. This is a diff against the latest checkout (linux 2.6.35):

    --- a/drivers/net/altera_tse.c
    +++ b/drivers/net/altera_tse.c
    @@ -112,8 +112,10 @@ static int altera_tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
            mac_dev = (alt_tse_mac *) bus->priv;
     
            /* set MDIO address */
    -       writel(mii_id, &mac_dev->mdio_phy0_addr);
    -       mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
    +       //writel(mii_id, &mac_dev->mdio_phy0_addr);
    +       //mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
    +       writel(mii_id, &mac_dev->mdio_phy1_addr);
    +       mdio_regs = (unsigned int *) &mac_dev->mdio_phy1;
     
            /* get the data */
            data = readl(&mdio_regs);
    @@ -130,8 +132,10 @@ static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u1
            mac_dev = (alt_tse_mac *) bus->priv;
     
            /* set MDIO address */
    -       writel(mii_id, &mac_dev->mdio_phy0_addr);
    -       mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
    +       //writel(mii_id, &mac_dev->mdio_phy0_addr);
    +       //mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
    +       writel(mii_id, &mac_dev->mdio_phy1_addr);
    +       mdio_regs = (unsigned int *) &mac_dev->mdio_phy1;
     
            /* get the data */
            data = (unsigned int) value;