Ethernet problems on AM3517, possible regression?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We have both a CompuLab CM-T3517 and a Technexion TAM-3517 at the shop.  Both boards provide dual Ethernet support in an identical fashion.  One port uses the onboard EMAC tied to an SMSC LAN87xx series PHY.  The other is the old trusty SMSC LAN911X hooked up to the GPMC.

Both boards support both interfaces when loaded with their respective TI PSP-based images.  These unfortunately date clear back to 2.6.37 or even 2.6.32 however.  When upgrading to the 3.x series linux-omap kernel, we noticed we could get one or the other of these to work, _but not both simultaneously_.  If both are enabled in code, neither work.

Even when we can get one or the other working, we seem to be having some problems with autonegotiation and MAC addressing.  MAC addresses on the SMSC are still random.  On the EMAC port, as you can see from our code below, we have put a patch in that is letting us establish a fixed MAC address.  However, I'm not sure this is a proper method to use at this point.

We suspect issues are known to exist with the Ethernet ports as the CM-T3517 has mainlined Linux support, and its latest board file does not show any configuration for either Ethernet interface.  Support from the previous kernel versions has apparently been removed, despite patches being applied to it as recently as mid-last year:  http://lists.infradead.org/pipermail/linux-arm-kernel/2011-May/050430.html

We also suspect this is being caused by an address conflict of some sort between the two ports.  We are using a linux-omap kernel, version 3.2.0-rc6 that is a month or two old now.  We've been monitoring this list, and have noted that some changes have been checked in for SMSC, but have not been able to update our kernel source as we were in the midst of a heavy debugging exercise that ended late last evening.  We plan to migrate to the latest HEAD soon.  Neverthelss, we've not seen any of these board files update.  So, we're assuming there are still known issues here.

I have attached the relevant sections of the board file we've created 
for the TAM-3517 (the one we've played with the most) below.  It is based off the 
older board files from the TI PSP and various configurations we have seen in similar hardware
 board files (overo, am3517_evm, cm-t3517, etc.)  If you note the 
configurable defines at the top, we've tied various combinations of code
 with no success to date.


Would you folks please take a look?  Any help would be appreciated.  Thanks!

-----------------------------------------------------------------------------------------------------------------
__NOTES:__

***When we run with just the SMSC enabled, the device works:
...
[    1.119415] smsc911x: Driver version 2008-10-21
[    1.126739] smsc911x-mdio: probed
[    1.130554] smsc911x smsc911x: eth0: attached PHY driver [SMSC LAN8700] (mii_bus:phy_addr=ffffffff:01, irq=-1)
[    1.142456] smsc911x smsc911x: eth0: MAC Address: d6:b4:7d:2c:03:40
...
root@board:~# ifdown eth0
root@board:~# ifup eth0
[  187.145019] smsc911x smsc911x: eth0: SMSC911x/921x identified at 0xd086e000, IRQ: 313
...
(*NOTE: the MAC address is random!)

***When we run with just the EMAC enabled, the device works:
...
[    1.184112] davinci_mdio davinci_mdio.0: davinci mdio revision 1.5
[    1.190612] davinci_mdio davinci_mdio.0: detected phy mask fffffffe
[    1.197998] davinci_mdio.0: probed
[    1.201690] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver SMSC LAN8710/LAN8720
...
[  213.613555] davinci_mdio davinci_mdio.0: resetting idled controller
[  213.621704] net eth0: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=0:00, id=7c0f1)
[  215.621917] PHY: 0:00 - Link is Up - 100/Full
...

*** When we run with BOTH enabled, they show in boot but neither works:
[    1.135864] smsc911x: Driver version 2008-10-21
[    1.143249] smsc911x-mdio: probed
[    1.147064] smsc911x smsc911x: eth0: attached PHY driver [SMSC LAN8700] (mii_bus:phy_addr=ffffffff:01, irq=-1)
[    1.158966] smsc911x smsc911x: eth0: MAC Address: 7e:92:21:13:be:ec
[    1.207580] davinci_mdio davinci_mdio.0: davinci mdio revision 1.5
[    1.214080] davinci_mdio davinci_mdio.0: detected phy mask fffffffe
[    1.221405] davinci_mdio.0: probed
[    1.225097] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver SMSC LAN8710/LAN8720
...
root@board:~# ifup eth0
ifconfig: SIOCSIFFLAGS: Input/output error
ifconfig: SIOCSIFFLAGS: Input/output error
...
root@board:~# ifup eth1
[ 1034.624603] net eth1: PHY already attached
[ 1034.628936] net eth1: could not connect to phy ffffffff:01



-----------------------------------------------------------------------------------------------------------------

/*
 * linux/arch/arm/mach-omap2/board-tam3517.c
 *
 * Copyright (C) 2011
 * Author: Technexion + others
 *
 * Based on mach-omap2/board-tam3517.c from Technexion BSP release
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as  published by the
 * Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
 * whether express or implied; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/can/platform/ti_hecc.h>

#include <linux/mmc/host.h>

#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>

#include <mach/hardware.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>

#include <plat/board.h>
#include "common.h"
#include <plat/usb.h>
#include <plat/nand.h>
#include <plat/gpmc.h>

#include <mach/am35xx.h>

#include "mux.h"
#include "control.h"
#include "hsmmc.h"

/* custom settings */
#define ENABLE_EMAC_ETH    1 // this messes with the SMSC right now
#define USE_ALT__EMAC_ETH    0

#define ENABLE_SMSC_ETH    1 // this messes with the EMAC right now
#define USE_ALT__SMSC_ETH    0

{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{{{{{{{{{{{{{{{{{{{{{{{{{{{    SNIP   }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

/****************************************************************************
 *
 * SMSC LAN
 *
 ****************************************************************************/

#if ENABLE_SMSC_ETH && ( defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) )

#include <linux/smsc911x.h>
#include <plat/gpmc-smsc911x.h>

#define SMSC911X_GPIO_IRQ 153
#define SMSC911X_GPIO_RESET 142
#define SMSC911X_GPIO_CS 5

#if USE_ALT__SMSC_ETH // gpmc-smsc911x style

static struct omap_smsc911x_platform_data tam3517_smsc911x_cfg = {
    .id        = 0,
    .cs             = SMSC911X_GPIO_CS,
    .gpio_irq       = SMSC911X_GPIO_IRQ,
    .gpio_reset     = -EINVAL,
    .flags        = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
};

static void __init tam3517_init_smsc911x(void)
{
    gpmc_smsc911x_init(&tam3517_smsc911x_cfg);
}

#else // use older style


static struct resource tam3517_smsc911x_resources[] = {
    {
        .name    = "smsc911x-memory",
        .flags    = IORESOURCE_MEM,
    },
    {
        .start  = OMAP_GPIO_IRQ(SMSC911X_GPIO_IRQ),
        .end    = OMAP_GPIO_IRQ(SMSC911X_GPIO_IRQ),
        .flags    =  (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
    },
};

static struct smsc911x_platform_config smsc911x_config = {
    .phy_interface    = PHY_INTERFACE_MODE_MII,
    .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
    .irq_type       = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
    .flags          = SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
};

static struct platform_device tam3517_smsc911x_device = {
    .name        = "smsc911x",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(tam3517_smsc911x_resources),
    .resource    = tam3517_smsc911x_resources,
    .dev        = {
        .platform_data = &smsc911x_config,
    },
};

static void __init tam3517_init_smsc911x(void)
{
    unsigned long cs_mem_base;

    if (gpmc_cs_request(SMSC911X_GPIO_CS, SZ_16M, &cs_mem_base) < 0) {
        printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
        return;
    }

    tam3517_smsc911x_resources[0].start = cs_mem_base + 0x0;
    tam3517_smsc911x_resources[0].end   = cs_mem_base + 0xFF;

    if ((gpio_request(SMSC911X_GPIO_IRQ, "smsc911x irq") == 0) &&
        (gpio_direction_input(SMSC911X_GPIO_IRQ) == 0)) {
        gpio_export(SMSC911X_GPIO_IRQ, 0);
    } else {
        printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
        return;
    }

    omap_mux_init_gpio(SMSC911X_GPIO_IRQ, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE4);
    gpio_direction_input(SMSC911X_GPIO_IRQ);

    // next 2 lines redundant?
    tam3517_smsc911x_resources[1].start = OMAP_GPIO_IRQ(SMSC911X_GPIO_IRQ);
    tam3517_smsc911x_resources[1].end  = OMAP_GPIO_IRQ(SMSC911X_GPIO_IRQ);
    omap_mux_init_gpio(SMSC911X_GPIO_RESET, OMAP_PIN_INPUT_PULLUP|OMAP_MUX_MODE4);

    if (gpio_request(SMSC911X_GPIO_RESET, "smsc911x reset") < 0)
    {
        printk(KERN_ERR "can't get smsc911x reset GPIO\n");
        return;
    }
    
    gpio_direction_output(SMSC911X_GPIO_RESET, 0);
    mdelay(1);
    gpio_direction_output(SMSC911X_GPIO_RESET, 1);

}

#endif // USE_ALT__SMSC_ETH

#else
static inline void __init tam3517_init_smsc911x(void) { return; }
#endif

/****************************************************************************
 *
 * EMAC LAN
 *
 ****************************************************************************/
#if ENABLE_EMAC_ETH

#include <linux/davinci_emac.h>

#define AM35XX_EVM_MDIO_FREQUENCY    (1000000)

#if USE_ALT__EMAC_ETH // Use new standalone EMAC code for generic AM35xx?

#include "am35xx-emac.h"

#else // Use original Davinci EMAC code

static struct resource tam3517_mdio_resources[] = {
    {
        .start  = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET,
        .end    = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET +
              SZ_4K - 1,
        .flags  = IORESOURCE_MEM,
    },
};

static struct mdio_platform_data tam3517_mdio_pdata = {
    .bus_freq    = AM35XX_EVM_MDIO_FREQUENCY,
};

static struct platform_device tam3517_mdio_device = {
    .name        = "davinci_mdio",
    .id        = 0,
    .num_resources    = ARRAY_SIZE(tam3517_mdio_resources),
    .resource    = tam3517_mdio_resources,
    .dev.platform_data = &tam3517_mdio_pdata,
};

static struct emac_platform_data tam3517_emac_pdata = {
    .rmii_en    = 1,
};

static struct resource tam3517_emac_resources[] = {
    {
        .start  = AM35XX_IPSS_EMAC_BASE,
        .end    = AM35XX_IPSS_EMAC_BASE + 0x2FFFF,
        .flags  = IORESOURCE_MEM,
    }, {
        .start  = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
        .end    = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
        .flags  = IORESOURCE_IRQ,
    }, {
        .start  = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
        .end    = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
        .flags  = IORESOURCE_IRQ,
    }, {
        .start  = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
        .end    = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
        .flags  = IORESOURCE_IRQ,
    }, {
        .start  = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
        .end    = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
        .flags  = IORESOURCE_IRQ,
    },
};

static struct platform_device tam3517_emac_device = {
    .name        = "davinci_emac",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(tam3517_emac_resources),
    .resource    = tam3517_emac_resources,
};

static void tam3517_enable_emac_int(void)
{
    u32 regval;

    regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
    regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
        AM35XX_CPGMAC_C0_TX_PULSE_CLR |
        AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
        AM35XX_CPGMAC_C0_RX_THRESH_CLR);
    omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
    regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
}

static void tam3517_disable_emac_int(void)
{
    u32 regval;

    regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
    regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
        AM35XX_CPGMAC_C0_TX_PULSE_CLR);
    omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
    regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
}

static void tam3517_emac_ethernet_init(void) {
    u32 regval, mac_lo, mac_hi;

    mac_lo = omap_ctrl_readl(AM35XX_CONTROL_FUSE_EMAC_LSB);
    mac_hi = omap_ctrl_readl(AM35XX_CONTROL_FUSE_EMAC_MSB);

    tam3517_emac_pdata.mac_addr[0] = (u_int8_t)((mac_hi & 0xFF0000) >> 16);
    tam3517_emac_pdata.mac_addr[1] = (u_int8_t)((mac_hi & 0xFF00) >> 8);
    tam3517_emac_pdata.mac_addr[2] = (u_int8_t)((mac_hi & 0xFF) >> 0);
    tam3517_emac_pdata.mac_addr[3] = (u_int8_t)((mac_lo & 0xFF0000) >> 16);
    tam3517_emac_pdata.mac_addr[4] = (u_int8_t)((mac_lo & 0xFF00) >> 8);
    tam3517_emac_pdata.mac_addr[5] = (u_int8_t)((mac_lo & 0xFF) >> 0);

    tam3517_emac_pdata.ctrl_reg_offset        = AM35XX_EMAC_CNTRL_OFFSET;
    tam3517_emac_pdata.ctrl_mod_reg_offset        = AM35XX_EMAC_CNTRL_MOD_OFFSET;
    tam3517_emac_pdata.ctrl_ram_offset        = AM35XX_EMAC_CNTRL_RAM_OFFSET;
    tam3517_emac_pdata.ctrl_ram_size        = AM35XX_EMAC_CNTRL_RAM_SIZE;
    tam3517_emac_pdata.version            = EMAC_VERSION_2;
    tam3517_emac_pdata.hw_ram_addr            = AM35XX_EMAC_HW_RAM_ADDR;
    tam3517_emac_pdata.interrupt_enable        = tam3517_enable_emac_int;
    tam3517_emac_pdata.interrupt_disable        = tam3517_disable_emac_int;
    tam3517_emac_device.dev.platform_data        = &tam3517_emac_pdata;
/* taken care of with platform_add_devices() below
    platform_device_register(&tam3517_emac_device);
    platform_device_register(&tam3517_mdio_device);
*/
    clk_add_alias(NULL, dev_name(&tam3517_mdio_device.dev),
              NULL, &tam3517_emac_device.dev);

    regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
    regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
    omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
    regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
}

#endif  // USE_ALT__EMAC_ETH
#endif  // ENABLE_EMAC_ETH

{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{{{{{{{{{{{{{{{{{{{{{{{{{{{    SNIP   }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

/* --------------------------------------------------------- */

static struct omap_board_config_kernel tam3517_config[] = {};

/* --------------------------------------------------------- */
static struct platform_device *tam3517_devices[] __initdata = {
#if ENABLE_SMSC_ETH && !(USE_ALT__SMSC_ETH) && ( defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) )
    &tam3517_smsc911x_device,
#endif
#if 0 && ( defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE) )
    &tam3517_hecc_device,
#endif
    &tam3517_dss_device,
#if ENABLE_EMAC_ETH && !(USE_ALT__EMAC_ETH)
    &tam3517_mdio_device,
    &tam3517_emac_device,
#endif
#if 0 && ( defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) )
    &tam3517_keys_gpio,
#endif
};

/* ------------------------------------------------------------------- */

static void __init tam3517_init(void) {
    platform_add_devices(tam3517_devices, ARRAY_SIZE(tam3517_devices));
    omap_board_config = tam3517_config;
    omap_board_config_size = ARRAY_SIZE(tam3517_config);
    omap3_mux_init(tam3517_mux, OMAP_PACKAGE_CBC);
    omap_serial_init();
    tam3517_i2c_init();
        
    omap2_hsmmc_init(mmc);
        
    tam3517_usb_init();        
    tam3517_nand_init();

    /*Ethernet:  SMSC911x */
#if ENABLE_SMSC_ETH
    tam3517_init_smsc911x();
#endif

    /*Ethernet:  DaVinci EMAC */
#if ENABLE_EMAC_ETH
#if USE_ALT__EMAC_ETH
    am35xx_ethernet_init(AM35XX_EVM_MDIO_FREQUENCY, 1);
#else
    tam3517_emac_ethernet_init();
#endif  // USE_ALT__EMAC_ETH
#endif  // ENABLE_EMAC_ETH
    
}

MACHINE_START(TAM3517, "Technexion TAM3517")
    .atag_offset    = 0x100,
    .reserve    = omap_reserve,
    .map_io        = omap3_map_io,
    .init_early    = am35xx_init_early,
    .init_irq    = omap3_init_irq,
    .handle_irq    = omap3_intc_handle_irq,
    .init_machine    = tam3517_init,
    .timer        = &omap3_timer,
MACHINE_END
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux