diff options
| -rw-r--r-- | board/ge/bx50v3/bx50v3.c | 6 | ||||
| -rw-r--r-- | common/fdt_support.c | 10 | ||||
| -rw-r--r-- | configs/A10-OLinuXino-Lime_defconfig | 4 | ||||
| -rw-r--r-- | configs/A20-OLinuXino-Lime2_defconfig | 4 | ||||
| -rw-r--r-- | configs/A20-OLinuXino-Lime_defconfig | 4 | ||||
| -rw-r--r-- | configs/A20-OLinuXino_MICRO_defconfig | 4 | ||||
| -rw-r--r-- | doc/device-tree-bindings/net/fixed-link.txt | 30 | ||||
| -rw-r--r-- | drivers/net/bcm-sf2-eth-gmac.c | 113 | ||||
| -rw-r--r-- | drivers/net/bcm-sf2-eth.h | 4 | ||||
| -rw-r--r-- | drivers/net/phy/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/net/phy/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/phy/fixed.c | 82 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 23 | ||||
| -rw-r--r-- | drivers/net/sunxi_emac.c | 19 | ||||
| -rw-r--r-- | include/phy.h | 3 | ||||
| -rw-r--r-- | net/link_local.c | 2 |
16 files changed, 249 insertions, 70 deletions
diff --git a/board/ge/bx50v3/bx50v3.c b/board/ge/bx50v3/bx50v3.c index 2fc1144cdae..0acf655c0e5 100644 --- a/board/ge/bx50v3/bx50v3.c +++ b/board/ge/bx50v3/bx50v3.c @@ -103,8 +103,9 @@ static void setup_iomux_enet(void) /* Reset AR8033 PHY */ gpio_direction_output(IMX_GPIO_NR(1, 28), 0); - udelay(500); + mdelay(10); gpio_set_value(IMX_GPIO_NR(1, 28), 1); + mdelay(1); } static iomux_v3_cfg_t const usdhc2_pads[] = { @@ -306,7 +307,8 @@ static int mx6_rgmii_rework(struct phy_device *phydev) /* set debug port address: SerDes Test and System Mode Control */ phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); /* enable rgmii tx clock delay */ - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + /* set the reserved bits to avoid board specific voltage peak issue*/ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47); return 0; } diff --git a/common/fdt_support.c b/common/fdt_support.c index 55d4d6f6d44..c6a76b7ad29 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -482,7 +482,6 @@ void fdt_fixup_ethernet(void *fdt) /* Cycle through all aliases */ for (prop = 0; ; prop++) { const char *name; - int len = strlen("ethernet"); /* FDT might have been edited, recompute the offset */ offset = fdt_first_property_offset(fdt, @@ -495,8 +494,13 @@ void fdt_fixup_ethernet(void *fdt) break; path = fdt_getprop_by_offset(fdt, offset, &name, NULL); - if (!strncmp(name, "ethernet", len)) { - i = trailing_strtol(name); + if (!strncmp(name, "ethernet", 8)) { + /* Treat plain "ethernet" same as "ethernet0". */ + if (!strcmp(name, "ethernet")) + i = 0; + else + i = trailing_strtol(name); + if (i != -1) { if (i == 0) strcpy(mac, "ethaddr"); diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig index 1cd3f1fd98b..6634139ab86 100644 --- a/configs/A10-OLinuXino-Lime_defconfig +++ b/configs/A10-OLinuXino-Lime_defconfig @@ -14,6 +14,10 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set +CONFIG_NET_ETHADDR_EEPROM=y +CONFIG_NET_ETHADDR_EEPROM_I2C=y +CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 +CONFIG_I2C1_ENABLE=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index a4ade72d4a3..4c720b31095 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -21,6 +21,10 @@ CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_SPL_PARTITION_UUIDS is not set CONFIG_DFU_RAM=y CONFIG_ETH_DESIGNWARE=y +CONFIG_NET_ETHADDR_EEPROM=y +CONFIG_NET_ETHADDR_EEPROM_I2C=y +CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 +CONFIG_I2C1_ENABLE=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index 4fe4e4acf78..564ae256a35 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -16,6 +16,10 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_NET_ETHADDR_EEPROM=y +CONFIG_NET_ETHADDR_EEPROM_I2C=y +CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 +CONFIG_I2C1_ENABLE=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig index e1d91e3b085..93be13b4077 100644 --- a/configs/A20-OLinuXino_MICRO_defconfig +++ b/configs/A20-OLinuXino_MICRO_defconfig @@ -19,6 +19,10 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_NET_ETHADDR_EEPROM=y +CONFIG_NET_ETHADDR_EEPROM_I2C=y +CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 +CONFIG_I2C1_ENABLE=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/doc/device-tree-bindings/net/fixed-link.txt b/doc/device-tree-bindings/net/fixed-link.txt new file mode 100644 index 00000000000..5829bd81a22 --- /dev/null +++ b/doc/device-tree-bindings/net/fixed-link.txt @@ -0,0 +1,30 @@ +Fixed link Device Tree binding +------------------------------ + +Some Ethernet MACs have a "fixed link", and are not connected to a +normal MDIO-managed PHY device. For those situations, a Device Tree +binding allows to describe a "fixed link". + +Such a fixed link situation is described by creating a 'fixed-link' +sub-node of the Ethernet MAC device node, with the following +properties: + +* 'speed' (integer, mandatory), to indicate the link speed. Accepted + values are 10, 100 and 1000 +* 'full-duplex' (boolean, optional), to indicate that full duplex is + used. When absent, half duplex is assumed. +* 'pause' (boolean, optional), to indicate that pause should be + enabled. +* 'asym-pause' (boolean, optional), to indicate that asym_pause should + be enabled. + +Examples: + +ethernet@0 { + ... + fixed-link { + speed = <1000>; + full-duplex; + }; + ... +}; diff --git a/drivers/net/bcm-sf2-eth-gmac.c b/drivers/net/bcm-sf2-eth-gmac.c index f2853cfad25..9ff72fa1edc 100644 --- a/drivers/net/bcm-sf2-eth-gmac.c +++ b/drivers/net/bcm-sf2-eth-gmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2014 Broadcom Corporation. + * Copyright 2014-2017 Broadcom. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -28,6 +28,10 @@ } \ } +#define RX_BUF_SIZE_ALIGNED ALIGN(RX_BUF_SIZE, ARCH_DMA_MINALIGN) +#define TX_BUF_SIZE_ALIGNED ALIGN(TX_BUF_SIZE, ARCH_DMA_MINALIGN) +#define DESCP_SIZE_ALIGNED ALIGN(sizeof(dma64dd_t), ARCH_DMA_MINALIGN) + static int gmac_disable_dma(struct eth_dma *dma, int dir); static int gmac_enable_dma(struct eth_dma *dma, int dir); @@ -114,7 +118,7 @@ static void dma_tx_dump(struct eth_dma *dma) printf("TX Buffers:\n"); /* Initialize TX DMA descriptor table */ for (i = 0; i < TX_BUF_NUM; i++) { - bufp = (uint8_t *)(dma->tx_buf + i * TX_BUF_SIZE); + bufp = (uint8_t *)(dma->tx_buf + i * TX_BUF_SIZE_ALIGNED); printf("buf%d:0x%x; ", i, (uint32_t)bufp); } printf("\n"); @@ -145,7 +149,7 @@ static void dma_rx_dump(struct eth_dma *dma) printf("RX Buffers:\n"); for (i = 0; i < RX_BUF_NUM; i++) { - bufp = dma->rx_buf + i * RX_BUF_SIZE; + bufp = dma->rx_buf + i * RX_BUF_SIZE_ALIGNED; printf("buf%d:0x%x; ", i, (uint32_t)bufp); } printf("\n"); @@ -163,15 +167,15 @@ static int dma_tx_init(struct eth_dma *dma) /* clear descriptor memory */ memset((void *)(dma->tx_desc_aligned), 0, - TX_BUF_NUM * sizeof(dma64dd_t)); - memset(dma->tx_buf, 0, TX_BUF_NUM * TX_BUF_SIZE); + TX_BUF_NUM * DESCP_SIZE_ALIGNED); + memset(dma->tx_buf, 0, TX_BUF_NUM * TX_BUF_SIZE_ALIGNED); /* Initialize TX DMA descriptor table */ for (i = 0; i < TX_BUF_NUM; i++) { descp = (dma64dd_t *)(dma->tx_desc_aligned) + i; - bufp = dma->tx_buf + i * TX_BUF_SIZE; + bufp = dma->tx_buf + i * TX_BUF_SIZE_ALIGNED; /* clear buffer memory */ - memset((void *)bufp, 0, TX_BUF_SIZE); + memset((void *)bufp, 0, TX_BUF_SIZE_ALIGNED); ctrl = 0; /* if last descr set endOfTable */ @@ -187,10 +191,11 @@ static int dma_tx_init(struct eth_dma *dma) descp = dma->tx_desc_aligned; bufp = dma->tx_buf; flush_dcache_range((unsigned long)descp, - (unsigned long)(descp + - sizeof(dma64dd_t) * TX_BUF_NUM)); - flush_dcache_range((unsigned long)(bufp), - (unsigned long)(bufp + TX_BUF_SIZE * TX_BUF_NUM)); + (unsigned long)descp + + DESCP_SIZE_ALIGNED * TX_BUF_NUM); + flush_dcache_range((unsigned long)bufp, + (unsigned long)bufp + + TX_BUF_SIZE_ALIGNED * TX_BUF_NUM); /* initialize the DMA channel */ writel((uint32_t)(dma->tx_desc_aligned), GMAC0_DMA_TX_ADDR_LOW_ADDR); @@ -215,20 +220,20 @@ static int dma_rx_init(struct eth_dma *dma) /* clear descriptor memory */ memset((void *)(dma->rx_desc_aligned), 0, - RX_BUF_NUM * sizeof(dma64dd_t)); + RX_BUF_NUM * DESCP_SIZE_ALIGNED); /* clear buffer memory */ - memset(dma->rx_buf, 0, RX_BUF_NUM * RX_BUF_SIZE); + memset(dma->rx_buf, 0, RX_BUF_NUM * RX_BUF_SIZE_ALIGNED); /* Initialize RX DMA descriptor table */ for (i = 0; i < RX_BUF_NUM; i++) { descp = (dma64dd_t *)(dma->rx_desc_aligned) + i; - bufp = dma->rx_buf + i * RX_BUF_SIZE; + bufp = dma->rx_buf + i * RX_BUF_SIZE_ALIGNED; ctrl = 0; /* if last descr set endOfTable */ if (i == (RX_BUF_NUM - 1)) ctrl = D64_CTRL1_EOT; descp->ctrl1 = ctrl; - descp->ctrl2 = RX_BUF_SIZE; + descp->ctrl2 = RX_BUF_SIZE_ALIGNED; descp->addrlow = (uint32_t)bufp; descp->addrhigh = 0; @@ -240,10 +245,11 @@ static int dma_rx_init(struct eth_dma *dma) bufp = dma->rx_buf; /* flush descriptor and buffer */ flush_dcache_range((unsigned long)descp, - (unsigned long)(descp + - sizeof(dma64dd_t) * RX_BUF_NUM)); + (unsigned long)descp + + DESCP_SIZE_ALIGNED * RX_BUF_NUM); flush_dcache_range((unsigned long)(bufp), - (unsigned long)(bufp + RX_BUF_SIZE * RX_BUF_NUM)); + (unsigned long)bufp + + RX_BUF_SIZE_ALIGNED * RX_BUF_NUM); /* initailize the DMA channel */ writel((uint32_t)descp, GMAC0_DMA_RX_ADDR_LOW_ADDR); @@ -292,14 +298,12 @@ static int dma_deinit(struct eth_dma *dma) free(dma->tx_buf); dma->tx_buf = NULL; - free(dma->tx_desc); - dma->tx_desc = NULL; + free(dma->tx_desc_aligned); dma->tx_desc_aligned = NULL; free(dma->rx_buf); dma->rx_buf = NULL; - free(dma->rx_desc); - dma->rx_desc = NULL; + free(dma->rx_desc_aligned); dma->rx_desc_aligned = NULL; return 0; @@ -307,7 +311,7 @@ static int dma_deinit(struct eth_dma *dma) int gmac_tx_packet(struct eth_dma *dma, void *packet, int length) { - uint8_t *bufp = dma->tx_buf + dma->cur_tx_index * TX_BUF_SIZE; + uint8_t *bufp = dma->tx_buf + dma->cur_tx_index * TX_BUF_SIZE_ALIGNED; /* kick off the dma */ size_t len = length; @@ -348,10 +352,11 @@ int gmac_tx_packet(struct eth_dma *dma, void *packet, int length) descp->ctrl2 = ctrl; /* flush descriptor and buffer */ - flush_dcache_range((unsigned long)descp, - (unsigned long)(descp + sizeof(dma64dd_t))); + flush_dcache_range((unsigned long)dma->tx_desc_aligned, + (unsigned long)dma->tx_desc_aligned + + DESCP_SIZE_ALIGNED * TX_BUF_NUM); flush_dcache_range((unsigned long)bufp, - (unsigned long)(bufp + TX_BUF_SIZE)); + (unsigned long)bufp + TX_BUF_SIZE_ALIGNED); /* now update the dma last descriptor */ writel(last_desc, GMAC0_DMA_TX_PTR_ADDR); @@ -426,14 +431,15 @@ int gmac_check_rx_done(struct eth_dma *dma, uint8_t *buf) ; /* get the packet pointer that corresponds to the rx descriptor */ - bufp = dma->rx_buf + index * RX_BUF_SIZE; + bufp = dma->rx_buf + index * RX_BUF_SIZE_ALIGNED; descp = (dma64dd_t *)(dma->rx_desc_aligned) + index; /* flush descriptor and buffer */ - flush_dcache_range((unsigned long)descp, - (unsigned long)(descp + sizeof(dma64dd_t))); + flush_dcache_range((unsigned long)dma->rx_desc_aligned, + (unsigned long)dma->rx_desc_aligned + + DESCP_SIZE_ALIGNED * RX_BUF_NUM); flush_dcache_range((unsigned long)bufp, - (unsigned long)(bufp + RX_BUF_SIZE)); + (unsigned long)bufp + RX_BUF_SIZE_ALIGNED); buflen = (descp->ctrl2 & D64_CTRL2_BC_MASK); @@ -457,12 +463,13 @@ int gmac_check_rx_done(struct eth_dma *dma, uint8_t *buf) memcpy(buf, datap, rcvlen); /* update descriptor that is being added back on ring */ - descp->ctrl2 = RX_BUF_SIZE; + descp->ctrl2 = RX_BUF_SIZE_ALIGNED; descp->addrlow = (uint32_t)bufp; descp->addrhigh = 0; /* flush descriptor */ - flush_dcache_range((unsigned long)descp, - (unsigned long)(descp + sizeof(dma64dd_t))); + flush_dcache_range((unsigned long)dma->rx_desc_aligned, + (unsigned long)dma->rx_desc_aligned + + DESCP_SIZE_ALIGNED * RX_BUF_NUM); /* set the lastdscr for the rx ring */ writel(((uint32_t)descp) & D64_XP_LD_MASK, GMAC0_DMA_RX_PTR_ADDR); @@ -573,7 +580,7 @@ static int gmac_enable_dma(struct eth_dma *dma, int dir) * set the lastdscr for the rx ring */ writel(((uint32_t)(dma->rx_desc_aligned) + - (RX_BUF_NUM - 1) * RX_BUF_SIZE) & + (RX_BUF_NUM - 1) * RX_BUF_SIZE_ALIGNED) & D64_XP_LD_MASK, GMAC0_DMA_RX_PTR_ADDR); } @@ -893,54 +900,52 @@ int gmac_add(struct eth_device *dev) void *tmp; /* - * Desc has to be 16-byte aligned ? - * If it is 8-byte aligned by malloc, fail Tx + * Desc has to be 16-byte aligned. But for dcache flush it must be + * aligned to ARCH_DMA_MINALIGN. */ - tmp = malloc(sizeof(dma64dd_t) * TX_BUF_NUM + 8); + tmp = memalign(ARCH_DMA_MINALIGN, DESCP_SIZE_ALIGNED * TX_BUF_NUM); if (tmp == NULL) { printf("%s: Failed to allocate TX desc Buffer\n", __func__); return -1; } - dma->tx_desc = (void *)tmp; - dma->tx_desc_aligned = (void *)(((uint32_t)tmp) & (~0xf)); + dma->tx_desc_aligned = (void *)tmp; debug("TX Descriptor Buffer: %p; length: 0x%x\n", - dma->tx_desc_aligned, sizeof(dma64dd_t) * TX_BUF_NUM); + dma->tx_desc_aligned, DESCP_SIZE_ALIGNED * TX_BUF_NUM); - tmp = malloc(TX_BUF_SIZE * TX_BUF_NUM); + tmp = memalign(ARCH_DMA_MINALIGN, TX_BUF_SIZE_ALIGNED * TX_BUF_NUM); if (tmp == NULL) { printf("%s: Failed to allocate TX Data Buffer\n", __func__); - free(dma->tx_desc); + free(dma->tx_desc_aligned); return -1; } dma->tx_buf = (uint8_t *)tmp; debug("TX Data Buffer: %p; length: 0x%x\n", - dma->tx_buf, TX_BUF_SIZE * TX_BUF_NUM); + dma->tx_buf, TX_BUF_SIZE_ALIGNED * TX_BUF_NUM); - /* Desc has to be 16-byte aligned ? */ - tmp = malloc(sizeof(dma64dd_t) * RX_BUF_NUM + 8); + /* Desc has to be 16-byte aligned */ + tmp = memalign(ARCH_DMA_MINALIGN, DESCP_SIZE_ALIGNED * RX_BUF_NUM); if (tmp == NULL) { printf("%s: Failed to allocate RX Descriptor\n", __func__); - free(dma->tx_desc); + free(dma->tx_desc_aligned); free(dma->tx_buf); return -1; } - dma->rx_desc = tmp; - dma->rx_desc_aligned = (void *)(((uint32_t)tmp) & (~0xf)); + dma->rx_desc_aligned = (void *)tmp; debug("RX Descriptor Buffer: %p, length: 0x%x\n", - dma->rx_desc_aligned, sizeof(dma64dd_t) * RX_BUF_NUM); + dma->rx_desc_aligned, DESCP_SIZE_ALIGNED * RX_BUF_NUM); - tmp = malloc(RX_BUF_SIZE * RX_BUF_NUM); + tmp = memalign(ARCH_DMA_MINALIGN, RX_BUF_SIZE_ALIGNED * RX_BUF_NUM); if (tmp == NULL) { printf("%s: Failed to allocate RX Data Buffer\n", __func__); - free(dma->tx_desc); + free(dma->tx_desc_aligned); free(dma->tx_buf); - free(dma->rx_desc); + free(dma->rx_desc_aligned); return -1; } - dma->rx_buf = tmp; + dma->rx_buf = (uint8_t *)tmp; debug("RX Data Buffer: %p; length: 0x%x\n", - dma->rx_buf, RX_BUF_SIZE * RX_BUF_NUM); + dma->rx_buf, RX_BUF_SIZE_ALIGNED * RX_BUF_NUM); g_dmactrlflags = 0; diff --git a/drivers/net/bcm-sf2-eth.h b/drivers/net/bcm-sf2-eth.h index 6104affc51c..c4e2e010034 100644 --- a/drivers/net/bcm-sf2-eth.h +++ b/drivers/net/bcm-sf2-eth.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Broadcom Corporation. + * Copyright 2014-2017 Broadcom. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -30,8 +30,6 @@ enum { struct eth_dma { void *tx_desc_aligned; void *rx_desc_aligned; - void *tx_desc; - void *rx_desc; uint8_t *tx_buf; uint8_t *rx_buf; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 1d514e92d3b..e562a8ac1a7 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -90,4 +90,14 @@ config PHY_VITESSE config PHY_XILINX bool "Xilinx Ethernet PHYs support" +config PHY_FIXED + bool "Fixed-Link PHY" + depends on DM_ETH + help + Fixed PHY is used for having a 'fixed-link' to another MAC with a direct + connection (MII, RGMII, ...). + There is nothing like autoneogation and so + on, the link is always up with fixed speed and fixed duplex-setting. + More information: doc/device-tree-bindings/net/fixed-link.txt + endif #PHYLIB diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index d37297122ad..88c00a5cd35 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_PHY_TI) += ti.o obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o obj-$(CONFIG_PHY_VITESSE) += vitesse.o obj-$(CONFIG_PHY_MSCC) += mscc.o +obj-$(CONFIG_PHY_FIXED) += fixed.o diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c new file mode 100644 index 00000000000..df8235645ef --- /dev/null +++ b/drivers/net/phy/fixed.c @@ -0,0 +1,82 @@ +/* + * Fixed-Link phy + * + * Copyright 2017 Bernecker & Rainer Industrieelektronik GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <common.h> +#include <phy.h> +#include <dm.h> +#include <fdt_support.h> + +DECLARE_GLOBAL_DATA_PTR; + +int fixedphy_probe(struct phy_device *phydev) +{ + struct fixed_link *priv; + int ofnode = phydev->addr; + u32 val; + + /* check for mandatory properties within fixed-link node */ + val = fdt_getprop_u32_default_node(gd->fdt_blob, + ofnode, 0, "speed", 0); + if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000) { + printf("ERROR: no/invalid speed given in fixed-link node!"); + return -EINVAL; + } + + priv = malloc(sizeof(*priv)); + if (!priv) + return -ENOMEM; + memset(priv, 0, sizeof(*priv)); + + phydev->priv = priv; + phydev->addr = 0; + + priv->link_speed = val; + priv->duplex = fdtdec_get_bool(gd->fdt_blob, ofnode, "full-duplex"); + priv->pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "pause"); + priv->asym_pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "asym-pause"); + + /* fixed-link phy must not be reset by core phy code */ + phydev->flags |= PHY_FLAG_BROKEN_RESET; + + return 0; +} + +int fixedphy_startup(struct phy_device *phydev) +{ + struct fixed_link *priv = phydev->priv; + + phydev->asym_pause = priv->asym_pause; + phydev->pause = priv->pause; + phydev->duplex = priv->duplex; + phydev->speed = priv->link_speed; + phydev->link = 1; + + return 0; +} + +int fixedphy_shutdown(struct phy_device *phydev) +{ + return 0; +} + +static struct phy_driver fixedphy_driver = { + .uid = PHY_FIXED_ID, + .mask = 0xffffffff, + .name = "Fixed PHY", + .features = PHY_GBIT_FEATURES | SUPPORTED_MII, + .probe = fixedphy_probe, + .startup = fixedphy_startup, + .shutdown = fixedphy_shutdown, +}; + +int phy_fixed_init(void) +{ + phy_register(&fixedphy_driver); + return 0; +} diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 8db65749b11..8bacd991ad5 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -515,7 +515,9 @@ int phy_init(void) #ifdef CONFIG_PHY_MSCC phy_mscc_init(); #endif - +#ifdef CONFIG_PHY_FIXED + phy_fixed_init(); +#endif return 0; } @@ -854,9 +856,24 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr, struct eth_device *dev, phy_interface_t interface) #endif { - struct phy_device *phydev; + struct phy_device *phydev = NULL; +#ifdef CONFIG_PHY_FIXED + int sn; + const char *name; + sn = fdt_first_subnode(gd->fdt_blob, dev->of_offset); + while (sn > 0) { + name = fdt_get_name(gd->fdt_blob, sn, NULL); + if (name != NULL && strcmp(name, "fixed-link") == 0) { + phydev = phy_device_create(bus, + sn, PHY_FIXED_ID, interface); + break; + } + sn = fdt_next_subnode(gd->fdt_blob, sn); + } +#endif + if (phydev == NULL) + phydev = phy_find_by_mask(bus, 1 << addr, interface); - phydev = phy_find_by_mask(bus, 1 << addr, interface); if (phydev) phy_connect_dev(phydev, dev); else diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 11cd0ea0688..99339db4bf5 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -327,6 +327,20 @@ static void emac_reset(struct emac_eth_dev *priv) udelay(200); } +static int _sunxi_write_hwaddr(struct emac_eth_dev *priv, u8 *enetaddr) +{ + struct emac_regs *regs = priv->regs; + u32 enetaddr_lo, enetaddr_hi; + + enetaddr_lo = enetaddr[2] | (enetaddr[1] << 8) | (enetaddr[0] << 16); + enetaddr_hi = enetaddr[5] | (enetaddr[4] << 8) | (enetaddr[3] << 16); + + writel(enetaddr_hi, ®s->mac_a1); + writel(enetaddr_lo, ®s->mac_a0); + + return 0; +} + static int _sunxi_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr) { struct emac_regs *regs = priv->regs; @@ -350,10 +364,7 @@ static int _sunxi_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr) /* Set up EMAC */ emac_setup(priv); - writel(enetaddr[0] << 16 | enetaddr[1] << 8 | enetaddr[2], - ®s->mac_a1); - writel(enetaddr[3] << 16 | enetaddr[4] << 8 | enetaddr[5], - ®s->mac_a0); + _sunxi_write_hwaddr(priv, enetaddr); mdelay(1); diff --git a/include/phy.h b/include/phy.h index 5477496e0e4..f5fdc04b6ed 100644 --- a/include/phy.h +++ b/include/phy.h @@ -15,6 +15,8 @@ #include <linux/ethtool.h> #include <linux/mdio.h> +#define PHY_FIXED_ID 0xa5a55a5a + #define PHY_MAX_ADDR 32 #define PHY_FLAG_BROKEN_RESET (1 << 0) /* soft reset not supported */ @@ -267,6 +269,7 @@ int phy_ti_init(void); int phy_vitesse_init(void); int phy_xilinx_init(void); int phy_mscc_init(void); +int phy_fixed_init(void); int board_phy_config(struct phy_device *phydev); int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); diff --git a/net/link_local.c b/net/link_local.c index 27851b6b813..dfd240dfbcf 100644 --- a/net/link_local.c +++ b/net/link_local.c @@ -111,7 +111,7 @@ void link_local_start(void) net_set_state(NETLOOP_FAIL); return; } - net_netmask.s_addr = IN_CLASSB_NET; + net_netmask.s_addr = htonl(IN_CLASSB_NET); seed = seed_mac(); if (ip.s_addr == 0) |
