Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2016-10-13 13:38:49 -04:00
commit 44afdc4a12
12 changed files with 447 additions and 55 deletions

View 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");

View File

@ -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]);

View 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;
}

View 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 */

View 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,
};

View 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 */
@ -103,8 +103,16 @@
#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
@ -166,7 +174,17 @@
#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;
}

View 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(

View 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) = {

View File

@ -432,6 +432,8 @@
#define CONFIG_PHY_GIGE
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC
/* Enable Atheros phy driver */
#define CONFIG_PHY_ATHEROS
/*
* NOR Size = 16 MiB

View 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;
};

View 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);

View 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