]> git.sur5r.net Git - u-boot/commitdiff
Merge git://git.denx.de/u-boot-fdt
authorTom Rini <trini@konsulko.com>
Fri, 14 Oct 2016 00:03:33 +0000 (20:03 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 14 Oct 2016 00:03:33 +0000 (20:03 -0400)
12 files changed:
board/ti/am335x/board.c
cmd/net.c
drivers/net/cpsw.c
drivers/net/mvneta.c
drivers/net/phy/atheros.c
drivers/net/phy/mv88e61xx.c
drivers/net/rtl8169.c
drivers/usb/eth/smsc95xx.c
include/configs/am335x_evm.h
include/cpsw.h
net/eth-uclass.c
test/py/tests/test_net.py

index 0ed16ca15ae79d696a49e4e23e3830a3f2a25210..fc1353ae3b2c63d747beb61bbc19f84158d39635 100644 (file)
@@ -47,11 +47,19 @@ DECLARE_GLOBAL_DATA_PTR;
 #define GPIO_MUX_MII_CTRL      GPIO_TO_PIN(3, 10)
 #define GPIO_FET_SWITCH_CTRL   GPIO_TO_PIN(0, 7)
 #define GPIO_PHY_RESET         GPIO_TO_PIN(2, 5)
+#define GPIO_ETH0_MODE         GPIO_TO_PIN(0, 11)
+#define GPIO_ETH1_MODE         GPIO_TO_PIN(1, 26)
 
-#if defined(CONFIG_SPL_BUILD) || \
-       (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_DM_ETH))
 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
-#endif
+
+#define GPIO0_RISINGDETECT     (AM33XX_GPIO0_BASE + OMAP_GPIO_RISINGDETECT)
+#define GPIO1_RISINGDETECT     (AM33XX_GPIO1_BASE + OMAP_GPIO_RISINGDETECT)
+
+#define GPIO0_IRQSTATUS1       (AM33XX_GPIO0_BASE + OMAP_GPIO_IRQSTATUS1)
+#define GPIO1_IRQSTATUS1       (AM33XX_GPIO1_BASE + OMAP_GPIO_IRQSTATUS1)
+
+#define GPIO0_IRQSTATUSRAW     (AM33XX_GPIO0_BASE + 0x024)
+#define GPIO1_IRQSTATUSRAW     (AM33XX_GPIO1_BASE + 0x024)
 
 /*
  * Read header information from EEPROM into global structure.
@@ -492,9 +500,9 @@ void sdram_init(void)
 }
 #endif
 
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
+#if !defined(CONFIG_SPL_BUILD) || \
        (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-static void request_and_set_gpio(int gpio, char *name)
+static void request_and_set_gpio(int gpio, char *name, int val)
 {
        int ret;
 
@@ -510,7 +518,7 @@ static void request_and_set_gpio(int gpio, char *name)
                goto err_free_gpio;
        }
 
-       gpio_set_value(gpio, 1);
+       gpio_set_value(gpio, val);
 
        return;
 
@@ -518,7 +526,8 @@ err_free_gpio:
        gpio_free(gpio);
 }
 
-#define REQUEST_AND_SET_GPIO(N)        request_and_set_gpio(N, #N);
+#define REQUEST_AND_SET_GPIO(N)        request_and_set_gpio(N, #N, 1);
+#define REQUEST_AND_CLR_GPIO(N)        request_and_set_gpio(N, #N, 0);
 
 /**
  * RMII mode on ICEv2 board needs 50MHz clock. Given the clock
@@ -548,20 +557,76 @@ int board_init(void)
 #if defined(CONFIG_NOR) || defined(CONFIG_NAND)
        gpmc_init();
 #endif
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD))
-       int rv;
 
+#if !defined(CONFIG_SPL_BUILD) || \
+       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
        if (board_is_icev2()) {
+               int rv;
+               u32 reg;
+
                REQUEST_AND_SET_GPIO(GPIO_PR1_MII_CTRL);
-               REQUEST_AND_SET_GPIO(GPIO_MUX_MII_CTRL);
+               /* Make J19 status available on GPIO1_26 */
+               REQUEST_AND_CLR_GPIO(GPIO_MUX_MII_CTRL);
+
                REQUEST_AND_SET_GPIO(GPIO_FET_SWITCH_CTRL);
+               /*
+                * Both ports can be set as RMII-CPSW or MII-PRU-ETH using
+                * jumpers near the port. Read the jumper value and set
+                * the pinmux, external mux and PHY clock accordingly.
+                * As jumper line is overridden by PHY RX_DV pin immediately
+                * after bootstrap (power-up/reset), we need to sample
+                * it during PHY reset using GPIO rising edge detection.
+                */
                REQUEST_AND_SET_GPIO(GPIO_PHY_RESET);
+               /* Enable rising edge IRQ on GPIO0_11 and GPIO 1_26 */
+               reg = readl(GPIO0_RISINGDETECT) | BIT(11);
+               writel(reg, GPIO0_RISINGDETECT);
+               reg = readl(GPIO1_RISINGDETECT) | BIT(26);
+               writel(reg, GPIO1_RISINGDETECT);
+               /* Reset PHYs to capture the Jumper setting */
+               gpio_set_value(GPIO_PHY_RESET, 0);
+               udelay(2);      /* PHY datasheet states 1uS min. */
+               gpio_set_value(GPIO_PHY_RESET, 1);
+
+               reg = readl(GPIO0_IRQSTATUSRAW) & BIT(11);
+               if (reg) {
+                       writel(reg, GPIO0_IRQSTATUS1); /* clear irq */
+                       /* RMII mode */
+                       printf("ETH0, CPSW\n");
+               } else {
+                       /* MII mode */
+                       printf("ETH0, PRU\n");
+                       cdce913_data.pdiv3 = 4; /* 25MHz PHY clk */
+               }
+
+               reg = readl(GPIO1_IRQSTATUSRAW) & BIT(26);
+               if (reg) {
+                       writel(reg, GPIO1_IRQSTATUS1); /* clear irq */
+                       /* RMII mode */
+                       printf("ETH1, CPSW\n");
+                       gpio_set_value(GPIO_MUX_MII_CTRL, 1);
+               } else {
+                       /* MII mode */
+                       printf("ETH1, PRU\n");
+                       cdce913_data.pdiv2 = 4; /* 25MHz PHY clk */
+               }
+
+               /* disable rising edge IRQs */
+               reg = readl(GPIO0_RISINGDETECT) & ~BIT(11);
+               writel(reg, GPIO0_RISINGDETECT);
+               reg = readl(GPIO1_RISINGDETECT) & ~BIT(26);
+               writel(reg, GPIO1_RISINGDETECT);
 
                rv = setup_clock_synthesizer(&cdce913_data);
                if (rv) {
                        printf("Clock synthesizer setup failed %d\n", rv);
                        return rv;
                }
+
+               /* reset PHYs */
+               gpio_set_value(GPIO_PHY_RESET, 0);
+               udelay(2);      /* PHY datasheet states 1uS min. */
+               gpio_set_value(GPIO_PHY_RESET, 1);
        }
 #endif
 
@@ -571,6 +636,11 @@ int board_init(void)
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
+#if !defined(CONFIG_SPL_BUILD)
+       uint8_t mac_addr[6];
+       uint32_t mac_hi, mac_lo;
+#endif
+
 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
        int rc;
        char *name = NULL;
@@ -584,6 +654,39 @@ int board_late_init(void)
        set_board_info_env(name);
 #endif
 
+#if !defined(CONFIG_SPL_BUILD)
+       /* try reading mac address from efuse */
+       mac_lo = readl(&cdev->macid0l);
+       mac_hi = readl(&cdev->macid0h);
+       mac_addr[0] = mac_hi & 0xFF;
+       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       mac_addr[4] = mac_lo & 0xFF;
+       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       if (!getenv("ethaddr")) {
+               printf("<ethaddr> not set. Validating first E-fuse MAC\n");
+
+               if (is_valid_ethaddr(mac_addr))
+                       eth_setenv_enetaddr("ethaddr", mac_addr);
+       }
+
+       mac_lo = readl(&cdev->macid1l);
+       mac_hi = readl(&cdev->macid1h);
+       mac_addr[0] = mac_hi & 0xFF;
+       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       mac_addr[4] = mac_lo & 0xFF;
+       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       if (!getenv("eth1addr")) {
+               if (is_valid_ethaddr(mac_addr))
+                       eth_setenv_enetaddr("eth1addr", mac_addr);
+       }
+#endif
+
        return 0;
 }
 #endif
@@ -652,11 +755,15 @@ static struct cpsw_platform_data cpsw_data = {
 int board_eth_init(bd_t *bis)
 {
        int rv, n = 0;
+#if defined(CONFIG_USB_ETHER) && \
+       (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
        uint8_t mac_addr[6];
        uint32_t mac_hi, mac_lo;
-       __maybe_unused struct ti_am_eeprom *header;
 
-       /* try reading mac address from efuse */
+       /*
+        * use efuse mac address for USB ethernet as we know that
+        * both CPSW and USB ethernet will never be active at the same time
+        */
        mac_lo = readl(&cdev->macid0l);
        mac_hi = readl(&cdev->macid0h);
        mac_addr[0] = mac_hi & 0xFF;
@@ -665,32 +772,13 @@ int board_eth_init(bd_t *bis)
        mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
        mac_addr[4] = mac_lo & 0xFF;
        mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+#endif
+
 
 #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
        (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-       if (!getenv("ethaddr")) {
-               printf("<ethaddr> not set. Validating first E-fuse MAC\n");
-
-               if (is_valid_ethaddr(mac_addr))
-                       eth_setenv_enetaddr("ethaddr", mac_addr);
-       }
 
 #ifdef CONFIG_DRIVER_TI_CPSW
-
-       mac_lo = readl(&cdev->macid1l);
-       mac_hi = readl(&cdev->macid1h);
-       mac_addr[0] = mac_hi & 0xFF;
-       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
-       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
-       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
-       mac_addr[4] = mac_lo & 0xFF;
-       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-
-       if (!getenv("eth1addr")) {
-               if (is_valid_ethaddr(mac_addr))
-                       eth_setenv_enetaddr("eth1addr", mac_addr);
-       }
-
        if (read_eeprom() < 0)
                puts("Could not get board ID.\n");
 
index b2f3c7b709bc59f7449b86a540faaf78d1cce292..bed76e4bcb0899e5c368d09ddd33ed6873a1b789 100644 (file)
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -243,9 +243,6 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
                return CMD_RET_SUCCESS;
        }
 
-       /* flush cache */
-       flush_cache(load_addr, size);
-
        bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
 
        rcode = bootm_maybe_autostart(cmdtp, argv[0]);
index c3018fba3239900de76b7cae129a8850a8303a51..cbce683eea9ab13369a0a0d8c944daeb7aca92d2 100644 (file)
@@ -225,6 +225,18 @@ struct cpdma_chan {
        void                    *hdp, *cp, *rxfree;
 };
 
+/* AM33xx SoC specific definitions for the CONTROL port */
+#define AM33XX_GMII_SEL_MODE_MII       0
+#define AM33XX_GMII_SEL_MODE_RMII      1
+#define AM33XX_GMII_SEL_MODE_RGMII     2
+
+#define AM33XX_GMII_SEL_RGMII1_IDMODE  BIT(4)
+#define AM33XX_GMII_SEL_RGMII2_IDMODE  BIT(5)
+#define AM33XX_GMII_SEL_RMII1_IO_CLK_EN        BIT(6)
+#define AM33XX_GMII_SEL_RMII2_IO_CLK_EN        BIT(7)
+
+#define GMII_SEL_MODE_MASK             0x3
+
 #define desc_write(desc, fld, val)     __raw_writel((u32)(val), &(desc)->fld)
 #define desc_read(desc, fld)           __raw_readl(&(desc)->fld)
 #define desc_read_ptr(desc, fld)       ((void *)__raw_readl(&(desc)->fld))
@@ -1150,12 +1162,129 @@ static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
                                                  false);
 }
 
+static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
+                                phy_interface_t phy_mode)
+{
+       u32 reg;
+       u32 mask;
+       u32 mode = 0;
+       bool rgmii_id = false;
+       int slave = priv->data.active_slave;
+
+       reg = readl(priv->data.gmii_sel);
+
+       switch (phy_mode) {
+       case PHY_INTERFACE_MODE_RMII:
+               mode = AM33XX_GMII_SEL_MODE_RMII;
+               break;
+
+       case PHY_INTERFACE_MODE_RGMII:
+               mode = AM33XX_GMII_SEL_MODE_RGMII;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+               mode = AM33XX_GMII_SEL_MODE_RGMII;
+               rgmii_id = true;
+               break;
+
+       case PHY_INTERFACE_MODE_MII:
+       default:
+               mode = AM33XX_GMII_SEL_MODE_MII;
+               break;
+       };
+
+       mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6);
+       mode <<= slave * 2;
+
+       if (priv->data.rmii_clock_external) {
+               if (slave == 0)
+                       mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN;
+               else
+                       mode |= AM33XX_GMII_SEL_RMII2_IO_CLK_EN;
+       }
+
+       if (rgmii_id) {
+               if (slave == 0)
+                       mode |= AM33XX_GMII_SEL_RGMII1_IDMODE;
+               else
+                       mode |= AM33XX_GMII_SEL_RGMII2_IDMODE;
+       }
+
+       reg &= ~mask;
+       reg |= mode;
+
+       writel(reg, priv->data.gmii_sel);
+}
+
+static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
+                                phy_interface_t phy_mode)
+{
+       u32 reg;
+       u32 mask;
+       u32 mode = 0;
+       int slave = priv->data.active_slave;
+
+       reg = readl(priv->data.gmii_sel);
+
+       switch (phy_mode) {
+       case PHY_INTERFACE_MODE_RMII:
+               mode = AM33XX_GMII_SEL_MODE_RMII;
+               break;
+
+       case PHY_INTERFACE_MODE_RGMII:
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+               mode = AM33XX_GMII_SEL_MODE_RGMII;
+               break;
+
+       case PHY_INTERFACE_MODE_MII:
+       default:
+               mode = AM33XX_GMII_SEL_MODE_MII;
+               break;
+       };
+
+       switch (slave) {
+       case 0:
+               mask = GMII_SEL_MODE_MASK;
+               break;
+       case 1:
+               mask = GMII_SEL_MODE_MASK << 4;
+               mode <<= 4;
+               break;
+       default:
+               dev_err(priv->dev, "invalid slave number...\n");
+               return;
+       }
+
+       if (priv->data.rmii_clock_external)
+               dev_err(priv->dev, "RMII External clock is not supported\n");
+
+       reg &= ~mask;
+       reg |= mode;
+
+       writel(reg, priv->data.gmii_sel);
+}
+
+static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat,
+                        phy_interface_t phy_mode)
+{
+       if (!strcmp(compat, "ti,am3352-cpsw-phy-sel"))
+               cpsw_gmii_sel_am3352(priv, phy_mode);
+       if (!strcmp(compat, "ti,am43xx-cpsw-phy-sel"))
+               cpsw_gmii_sel_am3352(priv, phy_mode);
+       else if (!strcmp(compat, "ti,dra7xx-cpsw-phy-sel"))
+               cpsw_gmii_sel_dra7xx(priv, phy_mode);
+}
+
 static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_platdata(dev);
        struct cpsw_priv *priv = dev_get_priv(dev);
        struct gpio_desc *mode_gpios;
        const char *phy_mode;
+       const char *phy_sel_compat = NULL;
        const void *fdt = gd->fdt_blob;
        int node = dev->of_offset;
        int subnode;
@@ -1271,6 +1400,17 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
                                error("Not able to get gmii_sel reg address\n");
                                return -ENOENT;
                        }
+
+                       if (fdt_get_property(fdt, subnode, "rmii-clock-ext",
+                                            NULL))
+                               priv->data.rmii_clock_external = true;
+
+                       phy_sel_compat = fdt_getprop(fdt, subnode, "compatible",
+                                                    NULL);
+                       if (!phy_sel_compat) {
+                               error("Not able to get gmii_sel compatible\n");
+                               return -ENOENT;
+                       }
                }
        }
 
@@ -1293,20 +1433,9 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
                return -EINVAL;
        }
-       switch (pdata->phy_interface) {
-       case PHY_INTERFACE_MODE_MII:
-               writel(MII_MODE_ENABLE, priv->data.gmii_sel);
-               break;
-       case PHY_INTERFACE_MODE_RMII:
-               writel(RMII_MODE_ENABLE, priv->data.gmii_sel);
-               break;
-       case PHY_INTERFACE_MODE_RGMII:
-       case PHY_INTERFACE_MODE_RGMII_ID:
-       case PHY_INTERFACE_MODE_RGMII_RXID:
-       case PHY_INTERFACE_MODE_RGMII_TXID:
-               writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
-               break;
-       }
+
+       /* Select phy interface in control module */
+       cpsw_phy_sel(priv, phy_sel_compat, pdata->phy_interface);
 
        return 0;
 }
index 51bb569a92d001c837dae0c9874b0d009c6c02e3..00f378f0826aebe1414a0e8139612b3371e92525 100644 (file)
@@ -1619,7 +1619,7 @@ static int mvneta_probe(struct udevice *dev)
        /*
         * Allocate buffer area for descs and rx_buffers. This is only
         * done once for all interfaces. As only one interface can
-        * be active. Make this area DMA save by disabling the D-cache
+        * be active. Make this area DMA safe by disabling the D-cache
         */
        if (!buffer_loc.tx_descs) {
                /* Align buffer area for descs and rx_buffers to 1MiB */
index e57c4120a3e5b4a55f2b53e110bac70a857a39b8..b34cdd3d87dc02f8a01db2f10e895287790679fb 100644 (file)
@@ -8,6 +8,15 @@
  */
 #include <phy.h>
 
+#define AR803x_PHY_DEBUG_ADDR_REG      0x1d
+#define AR803x_PHY_DEBUG_DATA_REG      0x1e
+
+#define AR803x_DEBUG_REG_5             0x5
+#define AR803x_RGMII_TX_CLK_DLY                0x100
+
+#define AR803x_DEBUG_REG_0             0x0
+#define AR803x_RGMII_RX_CLK_DLY                0x8000
+
 static int ar8021_config(struct phy_device *phydev)
 {
        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
@@ -17,6 +26,32 @@ static int ar8021_config(struct phy_device *phydev)
        return 0;
 }
 
+static int ar8031_config(struct phy_device *phydev)
+{
+       if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+           phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
+               phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
+                         AR803x_DEBUG_REG_5);
+               phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
+                         AR803x_RGMII_TX_CLK_DLY);
+       }
+
+       if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+           phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
+               phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
+                         AR803x_DEBUG_REG_0);
+               phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
+                         AR803x_RGMII_RX_CLK_DLY);
+       }
+
+       phydev->supported = phydev->drv->features;
+
+       genphy_config_aneg(phydev);
+       genphy_restart_aneg(phydev);
+
+       return 0;
+}
+
 static int ar8035_config(struct phy_device *phydev)
 {
        int regval;
@@ -31,6 +66,22 @@ static int ar8035_config(struct phy_device *phydev)
        regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
 
+       if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
+               /* select debug reg 5 */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x5);
+               /* enable tx delay */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x0100);
+       }
+
+       if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) {
+               /* select debug reg 0 */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x0);
+               /* enable rx delay */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x8000);
+       }
+
        phydev->supported = phydev->drv->features;
 
        genphy_config_aneg(phydev);
@@ -54,7 +105,7 @@ static struct phy_driver AR8031_driver =  {
        .uid = 0x4dd074,
        .mask = 0xffffffef,
        .features = PHY_GBIT_FEATURES,
-       .config = ar8035_config,
+       .config = ar8031_config,
        .startup = genphy_startup,
        .shutdown = genphy_shutdown,
 };
index 74d56098b5c9823dbdb89c163b3f6552e42cc3a6..a2fd1686fc3b8366aec9ddf7673fee4ee4b9f182 100644 (file)
@@ -40,7 +40,7 @@
 
 #define PHY_AUTONEGOTIATE_TIMEOUT      5000
 
-#define PORT_COUNT                     7
+#define PORT_COUNT                     11
 #define PORT_MASK                      ((1 << PORT_COUNT) - 1)
 
 /* Device addresses */
 #define PORT_REG_STATUS_CMODE_1000BASE_X       0x9
 #define PORT_REG_STATUS_CMODE_SGMII            0xa
 
+#define PORT_REG_PHYS_CTRL_PCS_AN_EN   BIT(10)
+#define PORT_REG_PHYS_CTRL_PCS_AN_RST  BIT(9)
+#define PORT_REG_PHYS_CTRL_FC_VALUE    BIT(7)
+#define PORT_REG_PHYS_CTRL_FC_FORCE    BIT(6)
 #define PORT_REG_PHYS_CTRL_LINK_VALUE  BIT(5)
 #define PORT_REG_PHYS_CTRL_LINK_FORCE  BIT(4)
+#define PORT_REG_PHYS_CTRL_DUPLEX_VALUE        BIT(3)
+#define PORT_REG_PHYS_CTRL_DUPLEX_FORCE        BIT(2)
+#define PORT_REG_PHYS_CTRL_SPD1000     BIT(1)
+#define PORT_REG_PHYS_CTRL_SPD_MASK    (BIT(1) | BIT(0))
 
 #define PORT_REG_CTRL_PSTATE_SHIFT     0
 #define PORT_REG_CTRL_PSTATE_WIDTH     2
 #error Define CONFIG_MV88E61XX_CPU_PORT to the port the CPU is attached to
 #endif
 
+/*
+ *  These are ports without PHYs that may be wired directly
+ * to other serdes interfaces
+ */
+#ifndef CONFIG_MV88E61XX_FIXED_PORTS
+#define CONFIG_MV88E61XX_FIXED_PORTS 0
+#endif
+
 /* ID register values for different switch models */
+#define PORT_SWITCH_ID_6096            0x0980
+#define PORT_SWITCH_ID_6097            0x0990
 #define PORT_SWITCH_ID_6172            0x1720
 #define PORT_SWITCH_ID_6176            0x1760
 #define PORT_SWITCH_ID_6240            0x2400
@@ -580,7 +598,7 @@ static int mv88e61xx_port_enable(struct phy_device *phydev, u8 port)
 }
 
 static int mv88e61xx_port_set_vlan(struct phy_device *phydev, u8 port,
-                                                       u8 mask)
+                                                       u16 mask)
 {
        int val;
 
@@ -791,6 +809,27 @@ static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy)
        return 0;
 }
 
+static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
+{
+       int val;
+
+       val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
+       if (val < 0)
+               return val;
+
+       val &= ~(PORT_REG_PHYS_CTRL_SPD_MASK |
+                PORT_REG_PHYS_CTRL_FC_VALUE);
+       val |= PORT_REG_PHYS_CTRL_PCS_AN_EN |
+              PORT_REG_PHYS_CTRL_PCS_AN_RST |
+              PORT_REG_PHYS_CTRL_FC_FORCE |
+              PORT_REG_PHYS_CTRL_DUPLEX_VALUE |
+              PORT_REG_PHYS_CTRL_DUPLEX_FORCE |
+              PORT_REG_PHYS_CTRL_SPD1000;
+
+       return mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL,
+                                  val);
+}
+
 static int mv88e61xx_phy_config_port(struct phy_device *phydev, u8 phy)
 {
        int val;
@@ -909,6 +948,12 @@ static int mv88e61xx_phy_config(struct phy_device *phydev)
 
                        /* Return success if any PHY succeeds */
                        ret = 0;
+               } else if ((1 << i) & CONFIG_MV88E61XX_FIXED_PORTS) {
+                       res = mv88e61xx_fixed_port_setup(phydev, i);
+                       if (res < 0) {
+                               printf("Error configuring port %i\n", i);
+                               continue;
+                       }
                }
        }
 
@@ -974,9 +1019,21 @@ static struct phy_driver mv88e61xx_driver = {
        .shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver mv88e609x_driver = {
+       .name = "Marvell MV88E609x",
+       .uid = 0x1410c89,
+       .mask = 0xfffffff0,
+       .features = PHY_GBIT_FEATURES,
+       .probe = mv88e61xx_probe,
+       .config = mv88e61xx_phy_config,
+       .startup = mv88e61xx_phy_startup,
+       .shutdown = &genphy_shutdown,
+};
+
 int phy_mv88e61xx_init(void)
 {
        phy_register(&mv88e61xx_driver);
+       phy_register(&mv88e609x_driver);
 
        return 0;
 }
index 1cc0b40935c53bff2e4426a4282b7a7a28d8870e..a3f4423a20ca3d7196480b010cba2eb50f23f41f 100644 (file)
@@ -629,11 +629,12 @@ static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
        /* point to the current txb incase multiple tx_rings are used */
        ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
        memcpy(ptxb, (char *)packet, (int)length);
-       rtl_flush_buffer(ptxb, length);
 
        while (len < ETH_ZLEN)
                ptxb[len++] = '\0';
 
+       rtl_flush_buffer(ptxb, ALIGN(len, RTL8169_ALIGN));
+
        tpc->TxDescArray[entry].buf_Haddr = 0;
 #ifdef CONFIG_DM_ETH
        tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
index 7d9abfda3be19cc763c232de01c78e9a930f2c83..d4c8ea4a98aa5a44af0956a3418820c1625c5939 100644 (file)
@@ -519,9 +519,11 @@ static int smsc95xx_init_common(struct usb_device *udev, struct ueth_data *dev,
                debug("timeout waiting for PHY Reset\n");
                return -ETIMEDOUT;
        }
+#ifndef CONFIG_DM_ETH
        if (!priv->have_hwaddr && smsc95xx_init_mac_address(enetaddr, udev) ==
                        0)
                priv->have_hwaddr = 1;
+#endif
        if (!priv->have_hwaddr) {
                puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n");
                return -EADDRNOTAVAIL;
@@ -1022,6 +1024,19 @@ int smsc95xx_write_hwaddr(struct udevice *dev)
        return smsc95xx_write_hwaddr_common(udev, priv, pdata->enetaddr);
 }
 
+int smsc95xx_read_rom_hwaddr(struct udevice *dev)
+{
+       struct usb_device *udev = dev_get_parent_priv(dev);
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       int ret;
+
+       ret = smsc95xx_init_mac_address(pdata->enetaddr, udev);
+       if (ret)
+               memset(pdata->enetaddr, 0, 6);
+
+       return 0;
+}
+
 static int smsc95xx_eth_probe(struct udevice *dev)
 {
        struct smsc95xx_private *priv = dev_get_priv(dev);
@@ -1037,6 +1052,7 @@ static const struct eth_ops smsc95xx_eth_ops = {
        .free_pkt = smsc95xx_free_pkt,
        .stop   = smsc95xx_eth_stop,
        .write_hwaddr = smsc95xx_write_hwaddr,
+       .read_rom_hwaddr = smsc95xx_read_rom_hwaddr,
 };
 
 U_BOOT_DRIVER(smsc95xx_eth) = {
index 272c71b76b6a73fe1e35bb5a5b2b307b2e2d2971..daa7dd8b9f23047f50d4ac42f806d983f694abe7 100644 (file)
 #define CONFIG_PHY_GIGE
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_SMSC
+/* Enable Atheros phy driver */
+#define CONFIG_PHY_ATHEROS
 
 /*
  * NOR Size = 16 MiB
index 257d12a08d721eef149a31b466306cc2465774d6..f135e7bfe0cc6425aa567c61414e2d12d59aae80 100644 (file)
@@ -48,6 +48,7 @@ struct cpsw_platform_data {
        void    (*control)(int enabled);
        u32     host_port_num;
        u32     active_slave;
+       bool    rmii_clock_external;
        u8      version;
 };
 
index c15cc4d90bf47dffacdd1339077340b0c99dd36a..a32961e6ceaae8e819a247c1f30bac24b3bc370f 100644 (file)
@@ -227,6 +227,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
                case env_op_create:
                case env_op_overwrite:
                        eth_parse_enetaddr(value, pdata->enetaddr);
+                       eth_write_hwaddr(dev);
                        break;
                case env_op_delete:
                        memset(pdata->enetaddr, 0, 6);
index 4ab58b44248a80c6144b3bd5b45374bbb765de4d..0884051614f05942bac58d72da668b977196f769 100644 (file)
@@ -47,6 +47,15 @@ env__net_tftp_readable_file = {
     "size": 5058624,
     "crc32": "c2244b26",
 }
+
+# Details regarding a file that may be read from a NFS server. This variable
+# may be omitted or set to None if NFS testing is not possible or desired.
+env__net_nfs_readable_file = {
+    "fn": "ubtest-readable.bin",
+    "addr": 0x10000000,
+    "size": 5058624,
+    "crc32": "c2244b26",
+}
 """
 
 net_set_up = False
@@ -157,3 +166,43 @@ def test_net_tftpboot(u_boot_console):
 
     output = u_boot_console.run_command('crc32 %x $filesize' % addr)
     assert expected_crc in output
+
+@pytest.mark.buildconfigspec('cmd_nfs')
+def test_net_nfs(u_boot_console):
+    """Test the nfs command.
+
+    A file is downloaded from the NFS server, its size and optionally its
+    CRC32 are validated.
+
+    The details of the file to download are provided by the boardenv_* file;
+    see the comment at the beginning of this file.
+    """
+
+    if not net_set_up:
+        pytest.skip('Network not initialized')
+
+    f = u_boot_console.config.env.get('env__net_nfs_readable_file', None)
+    if not f:
+        pytest.skip('No NFS readable file to read')
+
+    addr = f.get('addr', None)
+    if not addr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    fn = f['fn']
+    output = u_boot_console.run_command('nfs %x %s' % (addr, fn))
+    expected_text = 'Bytes transferred = '
+    sz = f.get('size', None)
+    if sz:
+        expected_text += '%d' % sz
+    assert expected_text in output
+
+    expected_crc = f.get('crc32', None)
+    if not expected_crc:
+        return
+
+    if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y':
+        return
+
+    output = u_boot_console.run_command('crc32 %x $filesize' % addr)
+    assert expected_crc in output