Merge branch 'master' of git://git.denx.de/u-boot-i2c
authorTom Rini <trini@konsulko.com>
Tue, 16 Oct 2018 11:25:28 +0000 (07:25 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 16 Oct 2018 11:25:28 +0000 (07:25 -0400)
59 files changed:
Makefile
arch/arc/config.mk
arch/arc/lib/cpu.c
arch/arm/mach-sunxi/dram_sun50i_h6.c
arch/sandbox/include/asm/eth.h
board/Synology/ds414/cmd_syno.c
board/davinci/da8xxevm/da850evm.c
board/freescale/ls1088a/eth_ls1088aqds.c
board/freescale/ls1088a/eth_ls1088ardb.c
board/freescale/ls2080aqds/eth.c
board/freescale/ls2080ardb/eth_ls2080rdb.c
board/synopsys/axs10x/axs10x.c
board/synopsys/emdk/emdk.c
board/synopsys/hsdk/hsdk.c
board/synopsys/iot_devkit/iot_devkit.c
configs/da850_am18xxevm_defconfig
configs/da850evm_defconfig
configs/da850evm_nand_defconfig
configs/iot_devkit_defconfig
doc/device-tree-bindings/net/ti,dp83867.txt
drivers/mtd/mtd_uboot.c
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/spi_flash.c
drivers/net/dc2114x.c
drivers/net/eepro100.c
drivers/net/fsl-mc/mc.c
drivers/net/ldpaa_eth/ldpaa_eth.c
drivers/net/ldpaa_eth/ldpaa_eth.h
drivers/net/ldpaa_eth/ldpaa_wriop.c
drivers/net/mvneta.c
drivers/net/mvpp2.c
drivers/net/natsemi.c
drivers/net/ns8382x.c
drivers/net/pch_gbe.c
drivers/net/phy/ti.c
drivers/net/rtl8139.c
drivers/net/rtl8169.c
drivers/net/sandbox.c
drivers/spi/davinci_spi.c
drivers/usb/eth/lan7x.h
drivers/usb/gadget/ether.c
drivers/usb/gadget/rndis.c
include/configs/da850evm.h
include/dm/platform_data/spi_davinci.h [new file with mode: 0644]
include/dt-bindings/net/ti-dp83867.h
include/fsl-mc/ldpaa_wriop.h
include/linux/compat.h
include/linux/if_ether.h [new file with mode: 0644]
include/linux/mdio.h
include/linux/mii.h
include/net.h
include/phy_interface.h
include/usb_ether.h
lib/fdtdec.c
net/arp.c
net/arp.h
net/net.c
net/ping.c
test/dm/eth.c

index aadd1ec..d03504e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 VERSION = 2018
 PATCHLEVEL = 11
 SUBLEVEL =
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME =
 
 # *DOCUMENTATION*
index d255c90..18005d9 100644 (file)
@@ -43,7 +43,7 @@ PLATFORM_CPPFLAGS += -mcpu=archs
 endif
 
 PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 -mno-sdata
-PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
+PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -fno-common
 
 # Needed for relocation
 LDFLAGS_FINAL += -pie --gc-sections
index 50cd7cd..a969a16 100644 (file)
@@ -60,7 +60,7 @@ const char *decode_identity(void)
        }
 }
 
-int print_cpuinfo(void)
+__weak int print_cpuinfo(void)
 {
        printf("CPU:   %s\n", decode_identity());
        return 0;
index 6b94cf3..5da90a2 100644 (file)
@@ -299,6 +299,8 @@ static void mctl_sys_init(struct dram_para *para)
 
        /* Put all DRAM-related blocks to reset state */
        clrbits_le32(&ccm->mbus_cfg, MBUS_ENABLE | MBUS_RESET);
+       clrbits_le32(&ccm->dram_gate_reset, BIT(0));
+       udelay(5);
        writel(0, &ccm->dram_gate_reset);
        clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
        clrbits_le32(&ccm->dram_clk_cfg, DRAM_MOD_RESET);
@@ -313,7 +315,9 @@ static void mctl_sys_init(struct dram_para *para)
        /* Configure DRAM mod clock */
        writel(DRAM_CLK_SRC_PLL5, &ccm->dram_clk_cfg);
        setbits_le32(&ccm->dram_clk_cfg, DRAM_CLK_UPDATE);
-       writel(BIT(0) | BIT(RESET_SHIFT), &ccm->dram_gate_reset);
+       writel(BIT(RESET_SHIFT), &ccm->dram_gate_reset);
+       udelay(5);
+       setbits_le32(&ccm->dram_gate_reset, BIT(0));
 
        /* Disable all channels */
        writel(0, &mctl_com->maer0);
index bfcd11b..477fa00 100644 (file)
@@ -13,4 +13,97 @@ void sandbox_eth_disable_response(int index, bool disable);
 
 void sandbox_eth_skip_timeout(void);
 
+/*
+ * sandbox_eth_arp_req_to_reply()
+ *
+ * Check for an arp request to be sent. If so, inject a reply
+ *
+ * @dev: device that received the packet
+ * @packet: pointer to the received pacaket buffer
+ * @len: length of received packet
+ * @return 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
+                                unsigned int len);
+
+/*
+ * sandbox_eth_ping_req_to_reply()
+ *
+ * Check for a ping request to be sent. If so, inject a reply
+ *
+ * @dev: device that received the packet
+ * @packet: pointer to the received pacaket buffer
+ * @len: length of received packet
+ * @return 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
+                                 unsigned int len);
+
+/*
+ * sandbox_eth_recv_arp_req()
+ *
+ * Inject an ARP request for this target
+ *
+ * @dev: device that received the packet
+ * @return 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_arp_req(struct udevice *dev);
+
+/*
+ * sandbox_eth_recv_ping_req()
+ *
+ * Inject a ping request for this target
+ *
+ * @dev: device that received the packet
+ * @return 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_ping_req(struct udevice *dev);
+
+/**
+ * A packet handler
+ *
+ * dev - device pointer
+ * pkt - pointer to the "sent" packet
+ * len - packet length
+ */
+typedef int sandbox_eth_tx_hand_f(struct udevice *dev, void *pkt,
+                                  unsigned int len);
+
+/**
+ * struct eth_sandbox_priv - memory for sandbox mock driver
+ *
+ * fake_host_hwaddr - MAC address of mocked machine
+ * fake_host_ipaddr - IP address of mocked machine
+ * disabled - Will not respond
+ * recv_packet_buffer - buffers of the packet returned as received
+ * recv_packet_length - lengths of the packet returned as received
+ * recv_packets - number of packets returned
+ * tx_handler - function to generate responses to sent packets
+ * priv - a pointer to some structure a test may want to keep track of
+ */
+struct eth_sandbox_priv {
+       uchar fake_host_hwaddr[ARP_HLEN];
+       struct in_addr fake_host_ipaddr;
+       bool disabled;
+       uchar * recv_packet_buffer[PKTBUFSRX];
+       int recv_packet_length[PKTBUFSRX];
+       int recv_packets;
+       sandbox_eth_tx_hand_f *tx_handler;
+       void *priv;
+};
+
+/*
+ * Set packet handler
+ *
+ * handler - The func ptr to call on send. If NULL, set to default handler
+ */
+void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler);
+
+/*
+ * Set priv ptr
+ *
+ * priv - priv void ptr to store in the device
+ */
+void sandbox_eth_set_priv(int index, void *priv);
+
 #endif /* __ETH_H */
index 34643ff..59e6fe0 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include "../drivers/ddr/marvell/axp/ddr3_init.h"
 
-#define ETH_ALEN               6
 #define ETHADDR_MAX            4
 #define SYNO_SN_TAG            "SN="
 #define SYNO_CHKSUM_TAG                "CHK="
index e8ec553..b0b29b3 100644 (file)
@@ -49,6 +49,33 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define CFG_MAC_ADDR_OFFSET    (flash->size - SZ_64K)
 
+#ifdef CONFIG_SPL_BUILD
+#include <ns16550.h>
+#include <dm/platform_data/spi_davinci.h>
+
+static const struct ns16550_platdata da850evm_serial = {
+       .base = DAVINCI_UART2_BASE,
+       .reg_shift = 2,
+       .clock = 150000000,
+       .fcr = UART_FCR_DEFVAL,
+};
+
+U_BOOT_DEVICE(da850evm_uart) = {
+       .name = "ns16550_serial",
+       .platdata = &da850evm_serial,
+};
+
+static const struct davinci_spi_platdata davinci_spi_data = {
+        .regs = (struct davinci_spi_regs *)0x01f0e000,
+        .num_cs = 4,
+};
+
+U_BOOT_DEVICE(davinci_spi) = {
+        .name = "davinci_spi",
+        .platdata = &davinci_spi_data,
+};
+#endif
+
 #ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
 static int get_mac_addr(u8 *addr)
 {
index 40b1a0e..f16b78c 100644 (file)
@@ -487,16 +487,16 @@ void ls1088a_handle_phy_interface_sgmii(int dpmac_id)
        case 0x3A:
                switch (dpmac_id) {
                case 1:
-                       wriop_set_phy_address(dpmac_id, riser_phy_addr[1]);
+                       wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[1]);
                        break;
                case 2:
-                       wriop_set_phy_address(dpmac_id, riser_phy_addr[0]);
+                       wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[0]);
                        break;
                case 3:
-                       wriop_set_phy_address(dpmac_id, riser_phy_addr[3]);
+                       wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[3]);
                        break;
                case 7:
-                       wriop_set_phy_address(dpmac_id, riser_phy_addr[2]);
+                       wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[2]);
                        break;
                default:
                        printf("WRIOP: Wrong DPMAC%d set to SGMII", dpmac_id);
@@ -532,13 +532,13 @@ void ls1088a_handle_phy_interface_qsgmii(int dpmac_id)
                case 4:
                case 5:
                case 6:
-                       wriop_set_phy_address(dpmac_id, dpmac_id + 9);
+                       wriop_set_phy_address(dpmac_id, 0, dpmac_id + 9);
                        break;
                case 7:
                case 8:
                case 9:
                case 10:
-                       wriop_set_phy_address(dpmac_id, dpmac_id + 1);
+                       wriop_set_phy_address(dpmac_id, 0, dpmac_id + 1);
                        break;
                }
 
@@ -567,7 +567,7 @@ void ls1088a_handle_phy_interface_xsgmii(int i)
        case 0x15:
        case 0x1D:
        case 0x1E:
-               wriop_set_phy_address(i, i + 26);
+               wriop_set_phy_address(i, 0, i + 26);
                ls1088a_qds_enable_SFP_TX(SFP_TX);
                break;
        default:
@@ -590,13 +590,13 @@ static void ls1088a_handle_phy_interface_rgmii(int dpmac_id)
 
        switch (dpmac_id) {
        case 4:
-               wriop_set_phy_address(dpmac_id, RGMII_PHY1_ADDR);
+               wriop_set_phy_address(dpmac_id, 0, RGMII_PHY1_ADDR);
                dpmac_info[dpmac_id].board_mux = EMI1_RGMII1;
                bus = mii_dev_for_muxval(EMI1_RGMII1);
                wriop_set_mdio(dpmac_id, bus);
                break;
        case 5:
-               wriop_set_phy_address(dpmac_id, RGMII_PHY2_ADDR);
+               wriop_set_phy_address(dpmac_id, 0, RGMII_PHY2_ADDR);
                dpmac_info[dpmac_id].board_mux = EMI1_RGMII2;
                bus = mii_dev_for_muxval(EMI1_RGMII2);
                wriop_set_mdio(dpmac_id, bus);
index 418f362..a2b52a8 100644 (file)
@@ -55,16 +55,17 @@ int board_eth_init(bd_t *bis)
                 * a MAC has no PHY address, we give a PHY address to XFI
                 * MAC error.
                 */
-               wriop_set_phy_address(WRIOP1_DPMAC1, 0x0a);
-               wriop_set_phy_address(WRIOP1_DPMAC2, AQ_PHY_ADDR1);
-               wriop_set_phy_address(WRIOP1_DPMAC3, QSGMII1_PORT1_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC4, QSGMII1_PORT2_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC5, QSGMII1_PORT3_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC6, QSGMII1_PORT4_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC7, QSGMII2_PORT1_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC8, QSGMII2_PORT2_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC9, QSGMII2_PORT3_PHY_ADDR);
-               wriop_set_phy_address(WRIOP1_DPMAC10, QSGMII2_PORT4_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC1, 0, 0x0a);
+               wriop_set_phy_address(WRIOP1_DPMAC2, 0, AQ_PHY_ADDR1);
+               wriop_set_phy_address(WRIOP1_DPMAC3, 0, QSGMII1_PORT1_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC4, 0, QSGMII1_PORT2_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC5, 0, QSGMII1_PORT3_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC6, 0, QSGMII1_PORT4_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC7, 0, QSGMII2_PORT1_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC8, 0, QSGMII2_PORT2_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC9, 0, QSGMII2_PORT3_PHY_ADDR);
+               wriop_set_phy_address(WRIOP1_DPMAC10, 0,
+                                     QSGMII2_PORT4_PHY_ADDR);
 
                break;
        default:
index 989d57e..f706fd4 100644 (file)
@@ -623,7 +623,7 @@ void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
                switch (++slot) {
                case 1:
                        /* Slot housing a SGMII riser card? */
-                       wriop_set_phy_address(dpmac_id,
+                       wriop_set_phy_address(dpmac_id, 0,
                                              riser_phy_addr[dpmac_id - 1]);
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
                        bus = mii_dev_for_muxval(EMI1_SLOT1);
@@ -631,7 +631,7 @@ void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
                        break;
                case 2:
                        /* Slot housing a SGMII riser card? */
-                       wriop_set_phy_address(dpmac_id,
+                       wriop_set_phy_address(dpmac_id, 0,
                                              riser_phy_addr[dpmac_id - 1]);
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
                        bus = mii_dev_for_muxval(EMI1_SLOT2);
@@ -641,18 +641,18 @@ void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
                        if (slot == EMI_NONE)
                                return;
                        if (serdes1_prtcl == 0x39) {
-                               wriop_set_phy_address(dpmac_id,
+                               wriop_set_phy_address(dpmac_id, 0,
                                        riser_phy_addr[dpmac_id - 2]);
                                if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
                                                                env_hwconfig))
-                                       wriop_set_phy_address(dpmac_id,
+                                       wriop_set_phy_address(dpmac_id, 0,
                                                riser_phy_addr[dpmac_id - 3]);
                        } else {
-                               wriop_set_phy_address(dpmac_id,
+                               wriop_set_phy_address(dpmac_id, 0,
                                        riser_phy_addr[dpmac_id - 2]);
                                if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
                                                                env_hwconfig))
-                                       wriop_set_phy_address(dpmac_id,
+                                       wriop_set_phy_address(dpmac_id, 0,
                                                riser_phy_addr[dpmac_id - 3]);
                        }
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
@@ -691,7 +691,7 @@ serdes2:
                        break;
                case 4:
                        /* Slot housing a SGMII riser card? */
-                       wriop_set_phy_address(dpmac_id,
+                       wriop_set_phy_address(dpmac_id, 0,
                                              riser_phy_addr[dpmac_id - 9]);
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
                        bus = mii_dev_for_muxval(EMI1_SLOT4);
@@ -701,14 +701,14 @@ serdes2:
                        if (slot == EMI_NONE)
                                return;
                        if (serdes2_prtcl == 0x47) {
-                               wriop_set_phy_address(dpmac_id,
+                               wriop_set_phy_address(dpmac_id, 0,
                                              riser_phy_addr[dpmac_id - 10]);
                                if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
                                                                 env_hwconfig))
-                                       wriop_set_phy_address(dpmac_id,
+                                       wriop_set_phy_address(dpmac_id, 0,
                                                riser_phy_addr[dpmac_id - 11]);
                        } else {
-                               wriop_set_phy_address(dpmac_id,
+                               wriop_set_phy_address(dpmac_id, 0,
                                        riser_phy_addr[dpmac_id - 11]);
                        }
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
@@ -717,7 +717,7 @@ serdes2:
                        break;
                case 6:
                        /* Slot housing a SGMII riser card? */
-                       wriop_set_phy_address(dpmac_id,
+                       wriop_set_phy_address(dpmac_id, 0,
                                              riser_phy_addr[dpmac_id - 13]);
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
                        bus = mii_dev_for_muxval(EMI1_SLOT6);
@@ -775,7 +775,7 @@ void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
                switch (++slot) {
                case 1:
                        /* Slot housing a QSGMII riser card? */
-                       wriop_set_phy_address(dpmac_id, dpmac_id - 1);
+                       wriop_set_phy_address(dpmac_id, 0, dpmac_id - 1);
                        dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
                        bus = mii_dev_for_muxval(EMI1_SLOT1);
                        wriop_set_mdio(dpmac_id, bus);
@@ -819,7 +819,7 @@ void ls2080a_handle_phy_interface_xsgmii(int i)
                 * the XAUI card is used for the XFI MAC, which will cause
                 * error.
                 */
-               wriop_set_phy_address(i, i + 4);
+               wriop_set_phy_address(i, 0, i + 4);
                ls2080a_qds_enable_SFP_TX(SFP_TX);
 
                break;
index 45f1d60..62c7a7a 100644 (file)
@@ -50,21 +50,21 @@ int board_eth_init(bd_t *bis)
 
        switch (srds_s1) {
        case 0x2A:
-               wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
-               wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
-               wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
-               wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
-               wriop_set_phy_address(WRIOP1_DPMAC5, AQ_PHY_ADDR1);
-               wriop_set_phy_address(WRIOP1_DPMAC6, AQ_PHY_ADDR2);
-               wriop_set_phy_address(WRIOP1_DPMAC7, AQ_PHY_ADDR3);
-               wriop_set_phy_address(WRIOP1_DPMAC8, AQ_PHY_ADDR4);
+               wriop_set_phy_address(WRIOP1_DPMAC1, 0, CORTINA_PHY_ADDR1);
+               wriop_set_phy_address(WRIOP1_DPMAC2, 0, CORTINA_PHY_ADDR2);
+               wriop_set_phy_address(WRIOP1_DPMAC3, 0, CORTINA_PHY_ADDR3);
+               wriop_set_phy_address(WRIOP1_DPMAC4, 0, CORTINA_PHY_ADDR4);
+               wriop_set_phy_address(WRIOP1_DPMAC5, 0, AQ_PHY_ADDR1);
+               wriop_set_phy_address(WRIOP1_DPMAC6, 0, AQ_PHY_ADDR2);
+               wriop_set_phy_address(WRIOP1_DPMAC7, 0, AQ_PHY_ADDR3);
+               wriop_set_phy_address(WRIOP1_DPMAC8, 0, AQ_PHY_ADDR4);
 
                break;
        case 0x4B:
-               wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
-               wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
-               wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
-               wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
+               wriop_set_phy_address(WRIOP1_DPMAC1, 0, CORTINA_PHY_ADDR1);
+               wriop_set_phy_address(WRIOP1_DPMAC2, 0, CORTINA_PHY_ADDR2);
+               wriop_set_phy_address(WRIOP1_DPMAC3, 0, CORTINA_PHY_ADDR3);
+               wriop_set_phy_address(WRIOP1_DPMAC4, 0, CORTINA_PHY_ADDR4);
 
                break;
        default:
index af78127..c95f7af 100644 (file)
@@ -33,6 +33,13 @@ int board_mmc_init(bd_t *bis)
        return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct dwmci_host *host = mmc->priv;
+
+       return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 #define AXS_MB_CREG    0xE0011000
 
 int board_early_init_f(void)
index bbb946a..79cafef 100644 (file)
@@ -34,6 +34,13 @@ int board_mmc_init(bd_t *bis)
        return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct dwmci_host *host = mmc->priv;
+
+       return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 #define CREG_BASE              0xF0001000
 #define CREG_BOOT_OFFSET       0
 #define CREG_BOOT_WP_OFFSET    8
index fb4286f..b6aefdb 100644 (file)
@@ -1019,6 +1019,13 @@ int board_late_init(void)
        return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct dwmci_host *host = mmc->priv;
+
+       return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 int board_mmc_init(bd_t *bis)
 {
        struct dwmci_host *host = NULL;
@@ -1046,3 +1053,11 @@ int board_mmc_init(bd_t *bis)
 
        return 0;
 }
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+       printf("CPU:   ARC HS38 v2.1c\n");
+       return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
index c185d5c..f8838fb 100644 (file)
@@ -17,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define AHBCKDIV       (void *)(SYSCON_BASE + 0x04)
 #define APBCKDIV       (void *)(SYSCON_BASE + 0x08)
 #define APBCKEN                (void *)(SYSCON_BASE + 0x0C)
+#define RESET_REG      (void *)(SYSCON_BASE + 0x18)
 #define CLKSEL         (void *)(SYSCON_BASE + 0x24)
 #define CLKSTAT                (void *)(SYSCON_BASE + 0x28)
 #define PLLCON         (void *)(SYSCON_BASE + 0x2C)
@@ -67,6 +68,14 @@ static int set_cpu_freq(unsigned int clk)
                writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON);
                break;
 
+       case 136:
+               writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+               /* pll_off=1, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
+               writel((readl(PLLCON) & PLL_MASK_1) | 0x100111, PLLCON);
+               /* pll_off=0, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
+               writel((readl(PLLCON) & PLL_MASK_2) | 0x100111, PLLCON);
+               break;
+
        case 144:
                writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
                /* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
@@ -99,7 +108,7 @@ extern u8 __ram_end[];
  */
 int mach_cpu_init(void)
 {
-       int offset, freq;
+       int offset;
 
        /* Don't relocate U-Boot */
        gd->flags |= GD_FLG_SKIP_RELOC;
@@ -120,12 +129,12 @@ int mach_cpu_init(void)
        if (offset < 0)
                return offset;
 
-       freq = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
-       if (!freq)
+       gd->cpu_clk = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
+       if (!gd->cpu_clk)
                return -EINVAL;
 
        /* If CPU freq > 100 MHz, divide eFLASH clock by 2 */
-       if (freq > 100000000) {
+       if (gd->cpu_clk > 100000000) {
                u32 reg = readl(AHBCKDIV);
 
                reg &= ~(0xF << 8);
@@ -133,7 +142,7 @@ int mach_cpu_init(void)
                writel(reg, AHBCKDIV);
        }
 
-       return set_cpu_freq(freq);
+       return set_cpu_freq(gd->cpu_clk);
 }
 
 #define ARC_PERIPHERAL_BASE    0xF0000000
@@ -161,8 +170,32 @@ int board_mmc_init(bd_t *bis)
        return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct dwmci_host *host = mmc->priv;
+
+       return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
+#define IOTDK_RESET_SEQ                0x55AA6699
+
+void reset_cpu(ulong addr)
+{
+       writel(IOTDK_RESET_SEQ, RESET_REG);
+}
+
 int checkboard(void)
 {
        puts("Board: Synopsys IoT Development Kit\n");
        return 0;
 };
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+       char mhz[8];
+
+       printf("CPU:   ARC EM9D at %s MHz\n", strmhz(mhz, gd->cpu_clk));
+       return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
index 6745cd1..8487509 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
@@ -35,6 +36,8 @@ CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DM=y
 CONFIG_DA8XX_GPIO=y
index 6dc70dd..5df45ae 100644 (file)
@@ -7,6 +7,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
@@ -37,6 +38,8 @@ CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:512k(u-boot.ais),64k(u-boot-env),7552k(kernel-spare),64k(MAC-Address)"
 CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DM=y
index d13d832..20f8e0a 100644 (file)
@@ -7,9 +7,12 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
 CONFIG_BOOTDELAY=3
 CONFIG_VERSION_VARIABLE=y
index 1f0f9c3..1b6dd9e 100644 (file)
@@ -4,8 +4,9 @@ CONFIG_CPU_ARCEM6=y
 CONFIG_SYS_ICACHE_OFF=y
 CONFIG_SYS_DCACHE_OFF=y
 CONFIG_TARGET_IOT_DEVKIT=y
-CONFIG_SYS_TEXT_BASE=0x20000000
+CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_SYS_CLK_FREQ=16000000
+CONFIG_LOCALVERSION="-iotdk-1.0"
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_SYS_PROMPT="IoTDK# "
 # CONFIG_CMD_BOOTD is not set
@@ -17,7 +18,6 @@ CONFIG_SYS_PROMPT="IoTDK# "
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
@@ -25,6 +25,7 @@ CONFIG_DEFAULT_DEVICE_TREE="iot_devkit"
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+# CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
index cb77fdf..034146f 100644 (file)
@@ -8,6 +8,12 @@ Required properties:
                for applicable values
        - ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
                for applicable values
+       - enet-phy-lane-swap - Indicates that PHY will swap the TX/RX lanes to
+               compensate for the board being designed with the lanes swapped.
+       - enet-phy-no-lane-swap - Indicates that PHY will disable swap of the
+               TX/RX lanes.
+       - ti,clk-output-sel - Clock output select - see dt-bindings/net/ti-dp83867.h
+               for applicable values
 
 Default child nodes are standard Ethernet PHY device
 nodes as described in doc/devicetree/bindings/net/ethernet.txt
@@ -19,6 +25,8 @@ Example:
                ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
                ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
                ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+               enet-phy-lane-no-swap;
+               ti,clk-output-sel = <DP83867_CLK_O_SEL_CHN_A_TCLK>;
        };
 
 Datasheet can be found:
index 6a211d5..7d7a11c 100644 (file)
@@ -104,7 +104,10 @@ int mtd_probe_devices(void)
        mtd_probe_uclass_mtd_devs();
 
        /* Check if mtdparts/mtdids changed since last call, otherwise: exit */
-       if (!strcmp(mtdparts, old_mtdparts) && !strcmp(mtdids, old_mtdids))
+       if ((!mtdparts && !old_mtdparts && !mtdids && !old_mtdids) ||
+           (mtdparts && old_mtdparts && mtdids && old_mtdids &&
+            !strcmp(mtdparts, old_mtdparts) &&
+            !strcmp(mtdids, old_mtdids)))
                return 0;
 
        /* Update the local copy of mtdparts */
@@ -140,6 +143,10 @@ int mtd_probe_devices(void)
                }
        }
 
+       /* If either mtdparts or mtdids is empty, then exit */
+       if (!mtdparts || !mtdids)
+               return 0;
+
        /* Start the parsing by ignoring the extra 'mtdparts=' prefix, if any */
        if (strstr(mtdparts, "mtdparts="))
                mtdparts += 9;
index 4f63cac..26f5c7c 100644 (file)
@@ -32,6 +32,7 @@ enum spi_nor_option_flags {
 /* CFI Manufacture ID's */
 #define SPI_FLASH_CFI_MFR_SPANSION     0x01
 #define SPI_FLASH_CFI_MFR_STMICRO      0x20
+#define SPI_FLASH_CFI_MFR_MICRON       0x2C
 #define SPI_FLASH_CFI_MFR_MACRONIX     0xc2
 #define SPI_FLASH_CFI_MFR_SST          0xbf
 #define SPI_FLASH_CFI_MFR_WINBOND      0xef
index 9230060..a87bacd 100644 (file)
@@ -1091,6 +1091,7 @@ static int set_quad_mode(struct spi_flash *flash,
 #endif
 #ifdef CONFIG_SPI_FLASH_STMICRO
        case SPI_FLASH_CFI_MFR_STMICRO:
+       case SPI_FLASH_CFI_MFR_MICRON:
                debug("SF: QEB is volatile for %02x flash\n", JEDEC_MFR(info));
                return 0;
 #endif
@@ -1178,6 +1179,7 @@ int spi_flash_scan(struct spi_flash *flash)
 #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST)
        /* NOR protection support for STmicro/Micron chips and similar */
        if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_STMICRO ||
+           JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_MICRON ||
            JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST) {
                flash->flash_lock = stm_lock;
                flash->flash_unlock = stm_unlock;
index 8d7c271..e3c403c 100644 (file)
 #define TOUT_LOOP   1000000
 
 #define SETUP_FRAME_LEN 192
-#define ETH_ALEN       6
 
 struct de4x5_desc {
        volatile s32 status;
index ae65b64..2fe0ba6 100644 (file)
@@ -193,8 +193,6 @@ struct descriptor {                 /* A generic descriptor. */
 
 #define TOUT_LOOP              1000000
 
-#define ETH_ALEN               6
-
 static struct RxFD rx_ring[NUM_RX_DESC];       /* RX descriptor ring         */
 static struct TxFD tx_ring[NUM_TX_DESC];       /* TX descriptor ring         */
 static int rx_next;                    /* RX descriptor ring pointer */
index d9a897d..b245fbc 100644 (file)
@@ -363,8 +363,7 @@ static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type)
 
        for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
                /* port not enabled */
-               if ((wriop_is_enabled_dpmac(i) != 1) ||
-                   (wriop_get_phy_address(i) == -1))
+               if (wriop_is_enabled_dpmac(i) != 1)
                        continue;
 
                snprintf(ethname, ETH_NAME_LEN, "DPMAC%d@%s", i,
@@ -886,8 +885,7 @@ int fsl_mc_ldpaa_init(bd_t *bis)
        int i;
 
        for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++)
-               if ((wriop_is_enabled_dpmac(i) == 1) &&
-                   (wriop_get_phy_address(i) != -1))
+               if (wriop_is_enabled_dpmac(i) == 1)
                        ldpaa_eth_init(i, wriop_get_enet_if(i));
        return 0;
 }
index a25b7cd..73b7ba2 100644 (file)
@@ -23,21 +23,43 @@ static int init_phy(struct eth_device *dev)
        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
        struct phy_device *phydev = NULL;
        struct mii_dev *bus;
+       int phy_addr, phy_num;
+       int ret = 0;
 
        bus = wriop_get_mdio(priv->dpmac_id);
        if (bus == NULL)
                return 0;
 
-       phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
-                            dev, wriop_get_enet_if(priv->dpmac_id));
-       if (!phydev) {
-               printf("Failed to connect\n");
-               return -1;
+       for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+               phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num);
+               if (phy_addr < 0)
+                       continue;
+
+               phydev = phy_connect(bus, phy_addr, dev,
+                                    wriop_get_enet_if(priv->dpmac_id));
+               if (!phydev) {
+                       printf("Failed to connect\n");
+                       ret = -ENODEV;
+                       break;
+               }
+               wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev);
+               ret = phy_config(phydev);
+               if (ret)
+                       break;
        }
 
-       priv->phydev = phydev;
+       if (ret) {
+               for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+                       phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+                       if (!phydev)
+                               continue;
+
+                       free(phydev);
+                       wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
+               }
+       }
 
-       return phy_config(phydev);
+       return ret;
 }
 #endif
 
@@ -377,6 +399,70 @@ error:
        return err;
 }
 
+static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
+                                struct dpmac_link_state *state)
+{
+       phy_interface_t enet_if;
+       int phys_detected;
+#ifdef CONFIG_PHYLIB
+       struct phy_device *phydev = NULL;
+       int err, phy_num;
+#endif
+
+       /* let's start off with maximum capabilities */
+       enet_if = wriop_get_enet_if(priv->dpmac_id);
+       switch (enet_if) {
+       case PHY_INTERFACE_MODE_XGMII:
+               state->rate = SPEED_10000;
+               break;
+       default:
+               state->rate = SPEED_1000;
+               break;
+       }
+       state->up = 1;
+
+       phys_detected = 0;
+#ifdef CONFIG_PHYLIB
+       state->options |= DPMAC_LINK_OPT_AUTONEG;
+
+       /* start the phy devices one by one and update the dpmac state */
+       for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+               phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+               if (!phydev)
+                       continue;
+
+               phys_detected++;
+               err = phy_startup(phydev);
+               if (err) {
+                       printf("%s: Could not initialize\n", phydev->dev->name);
+                       state->up = 0;
+                       break;
+               }
+               if (phydev->link) {
+                       state->rate = min(state->rate, (uint32_t)phydev->speed);
+                       if (!phydev->duplex)
+                               state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
+                       if (!phydev->autoneg)
+                               state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+               } else {
+                       /* break out of loop even if one phy is down */
+                       state->up = 0;
+                       break;
+               }
+       }
+#endif
+       if (!phys_detected)
+               state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+
+       if (!state->up) {
+               state->rate = 0;
+               state->options = 0;
+               return -ENOLINK;
+       }
+
+       return 0;
+}
+
 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 {
        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
@@ -385,8 +471,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
        struct dpni_link_state link_state;
 #endif
        int err = 0;
-       struct mii_dev *bus;
-       phy_interface_t enet_if;
        struct dpni_queue d_queue;
 
        if (net_dev->state == ETH_STATE_ACTIVE)
@@ -407,47 +491,14 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
        if (err < 0)
                goto err_dpmac_setup;
 
-#ifdef CONFIG_PHYLIB
-       if (priv->phydev) {
-               err = phy_startup(priv->phydev);
-               if (err) {
-                       printf("%s: Could not initialize\n",
-                              priv->phydev->dev->name);
-                       goto err_dpamc_bind;
-               }
-       }
-#else
-       priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
-       memset(priv->phydev, 0, sizeof(struct phy_device));
-
-       priv->phydev->speed = SPEED_1000;
-       priv->phydev->link = 1;
-       priv->phydev->duplex = DUPLEX_FULL;
-#endif
-
-       bus = wriop_get_mdio(priv->dpmac_id);
-       enet_if = wriop_get_enet_if(priv->dpmac_id);
-       if ((bus == NULL) &&
-           (enet_if == PHY_INTERFACE_MODE_XGMII)) {
-               priv->phydev = (struct phy_device *)
-                               malloc(sizeof(struct phy_device));
-               memset(priv->phydev, 0, sizeof(struct phy_device));
-
-               priv->phydev->speed = SPEED_10000;
-               priv->phydev->link = 1;
-               priv->phydev->duplex = DUPLEX_FULL;
-       }
-
-       if (!priv->phydev->link) {
-               printf("%s: No link.\n", priv->phydev->dev->name);
-               err = -1;
-               goto err_dpamc_bind;
-       }
+       err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
+       if (err < 0)
+               goto err_dpmac_bind;
 
        /* DPMAC binding DPNI */
        err = ldpaa_dpmac_bind(priv);
        if (err)
-               goto err_dpamc_bind;
+               goto err_dpmac_bind;
 
        /* DPNI initialization */
        err = ldpaa_dpni_setup(priv);
@@ -476,18 +527,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
                return err;
        }
 
-       dpmac_link_state.rate = priv->phydev->speed;
-
-       if (priv->phydev->autoneg == AUTONEG_DISABLE)
-               dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
-       else
-               dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
-
-       if (priv->phydev->duplex == DUPLEX_HALF)
-               dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
-
-       dpmac_link_state.up = priv->phydev->link;
-
        err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
                                  priv->dpmac_handle, &dpmac_link_state);
        if (err < 0) {
@@ -530,7 +569,7 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
                goto err_qdid;
        }
 
-       return priv->phydev->link;
+       return dpmac_link_state.up;
 
 err_qdid:
 err_get_queue:
@@ -540,7 +579,7 @@ err_dpni_bind:
 err_dpbp_setup:
        dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 err_dpni_setup:
-err_dpamc_bind:
+err_dpmac_bind:
        dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
        dpmac_destroy(dflt_mc_io,
                      dflt_dprc_handle,
@@ -554,7 +593,8 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
        int err = 0;
 #ifdef CONFIG_PHYLIB
-       struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
+       struct phy_device *phydev = NULL;
+       int phy_num;
 #endif
 
        if ((net_dev->state == ETH_STATE_PASSIVE) ||
@@ -588,11 +628,10 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
                printf("dpni_disable() failed\n");
 
 #ifdef CONFIG_PHYLIB
-       if (priv->phydev && bus != NULL)
-               phy_shutdown(priv->phydev);
-       else {
-               free(priv->phydev);
-               priv->phydev = NULL;
+       for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+               phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+               if (phydev)
+                       phy_shutdown(phydev);
        }
 #endif
 
index ee784a5..3f9154b 100644 (file)
@@ -127,7 +127,6 @@ struct ldpaa_eth_priv {
        uint16_t tx_flow_id;
 
        enum ldpaa_eth_type type;       /* 1G or 10G ethernet */
-       struct phy_device *phydev;
 };
 
 struct dprc_endpoint dpmac_endpoint;
index 0731a79..06a284a 100644 (file)
@@ -22,10 +22,10 @@ __weak phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtc)
 void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
 {
        phy_interface_t enet_if;
+       int phy_num;
 
        dpmac_info[dpmac_id].enabled = 0;
        dpmac_info[dpmac_id].id = 0;
-       dpmac_info[dpmac_id].phy_addr = -1;
        dpmac_info[dpmac_id].enet_if = PHY_INTERFACE_MODE_NONE;
 
        enet_if = wriop_dpmac_enet_if(dpmac_id, lane_prtcl);
@@ -34,14 +34,23 @@ void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
                dpmac_info[dpmac_id].id = dpmac_id;
                dpmac_info[dpmac_id].enet_if = enet_if;
        }
+       for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+               dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+               dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+       }
 }
 
 void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if)
 {
+       int phy_num;
+
        dpmac_info[dpmac_id].enabled = 1;
        dpmac_info[dpmac_id].id = dpmac_id;
-       dpmac_info[dpmac_id].phy_addr = -1;
        dpmac_info[dpmac_id].enet_if = enet_if;
+       for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+               dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+               dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+       }
 }
 
 
@@ -58,47 +67,53 @@ static int wriop_dpmac_to_index(int dpmac_id)
        return -1;
 }
 
-void wriop_disable_dpmac(int dpmac_id)
+int wriop_disable_dpmac(int dpmac_id)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return;
+               return -ENODEV;
 
        dpmac_info[i].enabled = 0;
        wriop_dpmac_disable(dpmac_id);
+
+       return 0;
 }
 
-void wriop_enable_dpmac(int dpmac_id)
+int wriop_enable_dpmac(int dpmac_id)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return;
+               return -ENODEV;
 
        dpmac_info[i].enabled = 1;
        wriop_dpmac_enable(dpmac_id);
+
+       return 0;
 }
 
-u8 wriop_is_enabled_dpmac(int dpmac_id)
+int wriop_is_enabled_dpmac(int dpmac_id)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return -1;
+               return -ENODEV;
 
        return dpmac_info[i].enabled;
 }
 
 
-void wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
+int wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return;
+               return -ENODEV;
 
        dpmac_info[i].bus = bus;
+
+       return 0;
 }
 
 struct mii_dev *wriop_get_mdio(int dpmac_id)
@@ -111,44 +126,56 @@ struct mii_dev *wriop_get_mdio(int dpmac_id)
        return dpmac_info[i].bus;
 }
 
-void wriop_set_phy_address(int dpmac_id, int address)
+int wriop_set_phy_address(int dpmac_id, int phy_num, int address)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return;
+               return -ENODEV;
+       if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+               return -EINVAL;
+
+       dpmac_info[i].phy_addr[phy_num] = address;
 
-       dpmac_info[i].phy_addr = address;
+       return 0;
 }
 
-int wriop_get_phy_address(int dpmac_id)
+int wriop_get_phy_address(int dpmac_id, int phy_num)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return -1;
+               return -ENODEV;
+       if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+               return -EINVAL;
 
-       return dpmac_info[i].phy_addr;
+       return dpmac_info[i].phy_addr[phy_num];
 }
 
-void wriop_set_phy_dev(int dpmac_id, struct phy_device *phydev)
+int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
-               return;
+               return -ENODEV;
+       if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+               return -EINVAL;
 
-       dpmac_info[i].phydev = phydev;
+       dpmac_info[i].phydev[phy_num] = phydev;
+
+       return 0;
 }
 
-struct phy_device *wriop_get_phy_dev(int dpmac_id)
+struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num)
 {
        int i = wriop_dpmac_to_index(dpmac_id);
 
        if (i == -1)
                return NULL;
+       if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+               return NULL;
 
-       return dpmac_info[i].phydev;
+       return dpmac_info[i].phydev[phy_num];
 }
 
 phy_interface_t wriop_get_enet_if(int dpmac_id)
index ab697b9..8cb04b5 100644 (file)
@@ -34,14 +34,6 @@ DECLARE_GLOBAL_DATA_PTR;
 # error Marvell mvneta requires PHYLIB
 #endif
 
-/* Some linux -> U-Boot compatibility stuff */
-#define netdev_err(dev, fmt, args...)          \
-       printf(fmt, ##args)
-#define netdev_warn(dev, fmt, args...)         \
-       printf(fmt, ##args)
-#define netdev_info(dev, fmt, args...)         \
-       printf(fmt, ##args)
-
 #define CONFIG_NR_CPUS         1
 #define ETH_HLEN               14      /* Total octets in header */
 
index 62c0c2b..f34245b 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Some linux -> U-Boot compatibility stuff */
-#define netdev_err(dev, fmt, args...)          \
-       printf(fmt, ##args)
-#define netdev_warn(dev, fmt, args...)         \
-       printf(fmt, ##args)
-#define netdev_info(dev, fmt, args...)         \
-       printf(fmt, ##args)
-#define netdev_dbg(dev, fmt, args...)          \
-       printf(fmt, ##args)
-
-#define ETH_ALEN       6               /* Octets in one ethernet addr  */
-
 #define __verify_pcpu_ptr(ptr)                                         \
 do {                                                                   \
        const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL;    \
@@ -68,7 +56,6 @@ do {                                                                  \
 #define NET_SKB_PAD    max(32, MVPP2_CPU_D_CACHE_LINE_SIZE)
 
 #define CONFIG_NR_CPUS         1
-#define ETH_HLEN               ETHER_HDR_SIZE  /* Total octets in header */
 
 /* 2(HW hdr) 14(MAC hdr) 4(CRC) 32(extra for cache prefetch) */
 #define WRAP                   (2 + ETH_HLEN + 4 + 32)
index 0ed9bb5..86f6898 100644 (file)
@@ -61,7 +61,6 @@
 #define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
 
 #define DSIZE          0x00000FFF
-#define ETH_ALEN       6
 #define CRC_SIZE       4
 #define TOUT_LOOP      500000
 #define TX_BUF_SIZE    1536
index f941c15..ea7ece5 100644 (file)
@@ -59,7 +59,6 @@
 
 /* defines */
 #define DSIZE     0x00000FFF
-#define ETH_ALEN               6
 #define CRC_SIZE  4
 #define TOUT_LOOP   500000
 #define TX_BUF_SIZE    1536
index d31c45f..2286dd0 100644 (file)
@@ -429,7 +429,7 @@ static int pch_gbe_phy_init(struct udevice *dev)
        return 0;
 }
 
-int pch_gbe_probe(struct udevice *dev)
+static int pch_gbe_probe(struct udevice *dev)
 {
        struct pch_gbe_priv *priv;
        struct eth_pdata *plat = dev_get_platdata(dev);
@@ -464,7 +464,7 @@ int pch_gbe_probe(struct udevice *dev)
        return pch_gbe_phy_init(dev);
 }
 
-int pch_gbe_remove(struct udevice *dev)
+static int pch_gbe_remove(struct udevice *dev)
 {
        struct pch_gbe_priv *priv = dev_get_priv(dev);
 
index f870e6d..6db6edd 100644 (file)
@@ -24,6 +24,7 @@
 /* Extended Registers */
 #define DP83867_CFG4           0x0031
 #define DP83867_RGMIICTL       0x0032
+#define DP83867_STRAP_STS1     0x006E
 #define DP83867_RGMIIDCTL      0x0086
 #define DP83867_IO_MUX_CFG     0x0170
 
 #define DP83867_RGMII_TX_CLK_DELAY_EN          BIT(1)
 #define DP83867_RGMII_RX_CLK_DELAY_EN          BIT(0)
 
+/* STRAP_STS1 bits */
+#define DP83867_STRAP_STS1_RESERVED            BIT(11)
+
 /* PHY CTRL bits */
 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT         14
+#define DP83867_PHYCR_RESERVED_MASK    BIT(11)
 #define DP83867_MDI_CROSSOVER          5
 #define DP83867_MDI_CROSSOVER_AUTO     2
 #define DP83867_MDI_CROSSOVER_MDIX     2
 
 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX    0x0
 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN    0x1f
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT     8
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK      \
+               GENMASK(0x1f, DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT)
+
+/* CFG4 bits */
+#define DP83867_CFG4_PORT_MIRROR_EN            BIT(0)
+
+enum {
+       DP83867_PORT_MIRRORING_KEEP,
+       DP83867_PORT_MIRRORING_EN,
+       DP83867_PORT_MIRRORING_DIS,
+};
 
 struct dp83867_private {
        int rx_id_delay;
@@ -95,6 +112,8 @@ struct dp83867_private {
        int fifo_depth;
        int io_impedance;
        bool rxctrl_strap_quirk;
+       int port_mirroring;
+       int clk_output_sel;
 };
 
 /**
@@ -163,6 +182,26 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
        phy_write(phydev, addr, MII_MMD_DATA, data);
 }
 
+static int dp83867_config_port_mirroring(struct phy_device *phydev)
+{
+       struct dp83867_private *dp83867 =
+               (struct dp83867_private *)phydev->priv;
+       u16 val;
+
+       val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+                                   phydev->addr);
+
+       if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN)
+               val |= DP83867_CFG4_PORT_MIRROR_EN;
+       else
+               val &= ~DP83867_CFG4_PORT_MIRROR_EN;
+
+       phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+                              phydev->addr, val);
+
+       return 0;
+}
+
 #if defined(CONFIG_DM_ETH)
 /**
  * dp83867_data_init - Convenience function for setting PHY specific data
@@ -173,6 +212,18 @@ static int dp83867_of_init(struct phy_device *phydev)
 {
        struct dp83867_private *dp83867 = phydev->priv;
        ofnode node;
+       u16 val;
+
+       /* Optional configuration */
+
+       /*
+        * Keep the default value if ti,clk-output-sel is not set
+        * or to high
+        */
+
+       dp83867->clk_output_sel =
+               ofnode_read_u32_default(node, "ti,clk-output-sel",
+                                       DP83867_CLK_O_SEL_REF_CLK);
 
        node = phy_get_ofnode(phydev);
        if (!ofnode_valid(node))
@@ -197,6 +248,23 @@ static int dp83867_of_init(struct phy_device *phydev)
 
        dp83867->fifo_depth = ofnode_read_u32_default(node, "ti,fifo-depth",
                                                      -1);
+       if (ofnode_read_bool(node, "enet-phy-lane-swap"))
+               dp83867->port_mirroring = DP83867_PORT_MIRRORING_EN;
+
+       if (ofnode_read_bool(node, "enet-phy-lane-no-swap"))
+               dp83867->port_mirroring = DP83867_PORT_MIRRORING_DIS;
+
+
+       /* Clock output selection if muxing property is set */
+       if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
+               val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+                                           DP83867_DEVADDR, phydev->addr);
+               val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
+               val |= (dp83867->clk_output_sel <<
+                       DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
+               phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+                                      DP83867_DEVADDR, phydev->addr, val);
+       }
 
        return 0;
 }
@@ -218,7 +286,7 @@ static int dp83867_config(struct phy_device *phydev)
 {
        struct dp83867_private *dp83867;
        unsigned int val, delay, cfg2;
-       int ret;
+       int ret, bs;
 
        if (!phydev->priv) {
                dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL);
@@ -253,6 +321,26 @@ static int dp83867_config(struct phy_device *phydev)
                        (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
                if (ret)
                        goto err_out;
+
+               /* The code below checks if "port mirroring" N/A MODE4 has been
+                * enabled during power on bootstrap.
+                *
+                * Such N/A mode enabled by mistake can put PHY IC in some
+                * internal testing mode and disable RGMII transmission.
+                *
+                * In this particular case one needs to check STRAP_STS1
+                * register's bit 11 (marked as RESERVED).
+                */
+
+               bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1,
+                                          DP83867_DEVADDR, phydev->addr);
+               val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL);
+               if (bs & DP83867_STRAP_STS1_RESERVED) {
+                       val &= ~DP83867_PHYCR_RESERVED_MASK;
+                       phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
+                                 val);
+               }
+
        } else if (phy_interface_is_sgmii(phydev)) {
                phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
                          (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
@@ -315,6 +403,9 @@ static int dp83867_config(struct phy_device *phydev)
                }
        }
 
+       if (dp83867->port_mirroring != DP83867_PORT_MIRRORING_KEEP)
+               dp83867_config_port_mirroring(phydev);
+
        genphy_config_aneg(phydev);
        return 0;
 
index ea52343..590f8ce 100644 (file)
 
 #define RTL_TIMEOUT    100000
 
-#define ETH_FRAME_LEN          1514
-#define ETH_ALEN               6
-#define ETH_ZLEN               60
-
 /* PCI Tuning Parameters
    Threshold is bytes transferred to chip before transmission starts. */
 #define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
index e0e3a6d..a78f3d2 100644 (file)
@@ -102,10 +102,6 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
 #define RTL_R16(reg)           readw(ioaddr + (reg))
 #define RTL_R32(reg)           readl(ioaddr + (reg))
 
-#define ETH_FRAME_LEN  MAX_ETH_FRAME_SIZE
-#define ETH_ALEN       MAC_ADDR_LEN
-#define ETH_ZLEN       60
-
 #define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)(unsigned long)dev->priv, \
        (pci_addr_t)(unsigned long)a)
 #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)(unsigned long)dev->priv, \
index b71c8f8..decce2f 100644 (file)
 #include <dm.h>
 #include <malloc.h>
 #include <net.h>
+#include <asm/eth.h>
 #include <asm/test.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/**
- * struct eth_sandbox_priv - memory for sandbox mock driver
- *
- * fake_host_hwaddr: MAC address of mocked machine
- * fake_host_ipaddr: IP address of mocked machine
- * recv_packet_buffer: buffer of the packet returned as received
- * recv_packet_length: length of the packet returned as received
- */
-struct eth_sandbox_priv {
-       uchar fake_host_hwaddr[ARP_HLEN];
-       struct in_addr fake_host_ipaddr;
-       uchar *recv_packet_buffer;
-       int recv_packet_length;
-};
-
-static bool disabled[8] = {false};
 static bool skip_timeout;
 
 /*
@@ -40,7 +25,16 @@ static bool skip_timeout;
  */
 void sandbox_eth_disable_response(int index, bool disable)
 {
-       disabled[index] = disable;
+       struct udevice *dev;
+       struct eth_sandbox_priv *priv;
+       int ret;
+
+       ret = uclass_get_device(UCLASS_ETH, index, &dev);
+       if (ret)
+               return;
+
+       priv = dev_get_priv(dev);
+       priv->disabled = disable;
 }
 
 /*
@@ -53,103 +47,304 @@ void sandbox_eth_skip_timeout(void)
        skip_timeout = true;
 }
 
-static int sb_eth_start(struct udevice *dev)
+/*
+ * sandbox_eth_arp_req_to_reply()
+ *
+ * Check for an arp request to be sent. If so, inject a reply
+ *
+ * returns 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
+                                unsigned int len)
 {
        struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth = packet;
+       struct arp_hdr *arp;
+       struct ethernet_hdr *eth_recv;
+       struct arp_hdr *arp_recv;
 
-       debug("eth_sandbox: Start\n");
+       if (ntohs(eth->et_protlen) != PROT_ARP)
+               return -EAGAIN;
 
-       priv->recv_packet_buffer = net_rx_packets[0];
+       arp = packet + ETHER_HDR_SIZE;
+
+       if (ntohs(arp->ar_op) != ARPOP_REQUEST)
+               return -EAGAIN;
+
+       /* Don't allow the buffer to overrun */
+       if (priv->recv_packets >= PKTBUFSRX)
+               return 0;
+
+       /* store this as the assumed IP of the fake host */
+       priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
+
+       /* Formulate a fake response */
+       eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+       memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
+       memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+       eth_recv->et_protlen = htons(PROT_ARP);
+
+       arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
+       arp_recv->ar_hrd = htons(ARP_ETHER);
+       arp_recv->ar_pro = htons(PROT_IP);
+       arp_recv->ar_hln = ARP_HLEN;
+       arp_recv->ar_pln = ARP_PLEN;
+       arp_recv->ar_op = htons(ARPOP_REPLY);
+       memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
+       net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
+       memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
+       net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
+
+       priv->recv_packet_length[priv->recv_packets] =
+               ETHER_HDR_SIZE + ARP_HDR_SIZE;
+       ++priv->recv_packets;
 
        return 0;
 }
 
-static int sb_eth_send(struct udevice *dev, void *packet, int length)
+/*
+ * sandbox_eth_ping_req_to_reply()
+ *
+ * Check for a ping request to be sent. If so, inject a reply
+ *
+ * returns 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
+                                 unsigned int len)
 {
        struct eth_sandbox_priv *priv = dev_get_priv(dev);
        struct ethernet_hdr *eth = packet;
+       struct ip_udp_hdr *ip;
+       struct icmp_hdr *icmp;
+       struct ethernet_hdr *eth_recv;
+       struct ip_udp_hdr *ipr;
+       struct icmp_hdr *icmpr;
 
-       debug("eth_sandbox: Send packet %d\n", length);
+       if (ntohs(eth->et_protlen) != PROT_IP)
+               return -EAGAIN;
+
+       ip = packet + ETHER_HDR_SIZE;
+
+       if (ip->ip_p != IPPROTO_ICMP)
+               return -EAGAIN;
+
+       icmp = (struct icmp_hdr *)&ip->udp_src;
+
+       if (icmp->type != ICMP_ECHO_REQUEST)
+               return -EAGAIN;
+
+       /* Don't allow the buffer to overrun */
+       if (priv->recv_packets >= PKTBUFSRX)
+               return 0;
+
+       /* reply to the ping */
+       eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+       memcpy(eth_recv, packet, len);
+       ipr = (void *)eth_recv + ETHER_HDR_SIZE;
+       icmpr = (struct icmp_hdr *)&ipr->udp_src;
+       memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
+       memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+       ipr->ip_sum = 0;
+       ipr->ip_off = 0;
+       net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
+       net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr);
+       ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
+
+       icmpr->type = ICMP_ECHO_REPLY;
+       icmpr->checksum = 0;
+       icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
+
+       priv->recv_packet_length[priv->recv_packets] = len;
+       ++priv->recv_packets;
+
+       return 0;
+}
+
+/*
+ * sandbox_eth_recv_arp_req()
+ *
+ * Inject an ARP request for this target
+ *
+ * returns 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_arp_req(struct udevice *dev)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth_recv;
+       struct arp_hdr *arp_recv;
+
+       /* Don't allow the buffer to overrun */
+       if (priv->recv_packets >= PKTBUFSRX)
+               return -EOVERFLOW;
+
+       /* Formulate a fake request */
+       eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+       memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN);
+       memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+       eth_recv->et_protlen = htons(PROT_ARP);
+
+       arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
+       arp_recv->ar_hrd = htons(ARP_ETHER);
+       arp_recv->ar_pro = htons(PROT_IP);
+       arp_recv->ar_hln = ARP_HLEN;
+       arp_recv->ar_pln = ARP_PLEN;
+       arp_recv->ar_op = htons(ARPOP_REQUEST);
+       memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
+       net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
+       memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN);
+       net_write_ip(&arp_recv->ar_tpa, net_ip);
+
+       priv->recv_packet_length[priv->recv_packets] =
+               ETHER_HDR_SIZE + ARP_HDR_SIZE;
+       ++priv->recv_packets;
+
+       return 0;
+}
+
+/*
+ * sandbox_eth_recv_ping_req()
+ *
+ * Inject a ping request for this target
+ *
+ * returns 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_ping_req(struct udevice *dev)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth_recv;
+       struct ip_udp_hdr *ipr;
+       struct icmp_hdr *icmpr;
+
+       /* Don't allow the buffer to overrun */
+       if (priv->recv_packets >= PKTBUFSRX)
+               return -EOVERFLOW;
+
+       /* Formulate a fake ping */
+       eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+
+       memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN);
+       memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+       eth_recv->et_protlen = htons(PROT_IP);
+
+       ipr = (void *)eth_recv + ETHER_HDR_SIZE;
+       ipr->ip_hl_v = 0x45;
+       ipr->ip_len = htons(IP_ICMP_HDR_SIZE);
+       ipr->ip_off = htons(IP_FLAGS_DFRAG);
+       ipr->ip_p = IPPROTO_ICMP;
+       ipr->ip_sum = 0;
+       net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr);
+       net_write_ip(&ipr->ip_dst, net_ip);
+       ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
+
+       icmpr = (struct icmp_hdr *)&ipr->udp_src;
+
+       icmpr->type = ICMP_ECHO_REQUEST;
+       icmpr->code = 0;
+       icmpr->checksum = 0;
+       icmpr->un.echo.id = 0;
+       icmpr->un.echo.sequence = htons(1);
+       icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
+
+       priv->recv_packet_length[priv->recv_packets] =
+               ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE;
+       ++priv->recv_packets;
+
+       return 0;
+}
 
-       if (dev->seq >= 0 && dev->seq < ARRAY_SIZE(disabled) &&
-           disabled[dev->seq])
+/*
+ * sb_default_handler()
+ *
+ * perform typical responses to simple ping
+ *
+ * dev - device pointer
+ * pkt - "sent" packet buffer
+ * len - length of packet
+ */
+static int sb_default_handler(struct udevice *dev, void *packet,
+                             unsigned int len)
+{
+       if (!sandbox_eth_arp_req_to_reply(dev, packet, len))
+               return 0;
+       if (!sandbox_eth_ping_req_to_reply(dev, packet, len))
                return 0;
 
-       if (ntohs(eth->et_protlen) == PROT_ARP) {
-               struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
-
-               if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
-                       struct ethernet_hdr *eth_recv;
-                       struct arp_hdr *arp_recv;
-
-                       /* store this as the assumed IP of the fake host */
-                       priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
-                       /* Formulate a fake response */
-                       eth_recv = (void *)priv->recv_packet_buffer;
-                       memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
-                       memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
-                              ARP_HLEN);
-                       eth_recv->et_protlen = htons(PROT_ARP);
-
-                       arp_recv = (void *)priv->recv_packet_buffer +
-                               ETHER_HDR_SIZE;
-                       arp_recv->ar_hrd = htons(ARP_ETHER);
-                       arp_recv->ar_pro = htons(PROT_IP);
-                       arp_recv->ar_hln = ARP_HLEN;
-                       arp_recv->ar_pln = ARP_PLEN;
-                       arp_recv->ar_op = htons(ARPOP_REPLY);
-                       memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr,
-                              ARP_HLEN);
-                       net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
-                       memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
-                       net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
-
-                       priv->recv_packet_length = ETHER_HDR_SIZE +
-                               ARP_HDR_SIZE;
-               }
-       } else if (ntohs(eth->et_protlen) == PROT_IP) {
-               struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
-
-               if (ip->ip_p == IPPROTO_ICMP) {
-                       struct icmp_hdr *icmp = (struct icmp_hdr *)&ip->udp_src;
-
-                       if (icmp->type == ICMP_ECHO_REQUEST) {
-                               struct ethernet_hdr *eth_recv;
-                               struct ip_udp_hdr *ipr;
-                               struct icmp_hdr *icmpr;
-
-                               /* reply to the ping */
-                               memcpy(priv->recv_packet_buffer, packet,
-                                      length);
-                               eth_recv = (void *)priv->recv_packet_buffer;
-                               ipr = (void *)priv->recv_packet_buffer +
-                                       ETHER_HDR_SIZE;
-                               icmpr = (struct icmp_hdr *)&ipr->udp_src;
-                               memcpy(eth_recv->et_dest, eth->et_src,
-                                      ARP_HLEN);
-                               memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
-                                      ARP_HLEN);
-                               ipr->ip_sum = 0;
-                               ipr->ip_off = 0;
-                               net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
-                               net_write_ip((void *)&ipr->ip_src,
-                                            priv->fake_host_ipaddr);
-                               ipr->ip_sum = compute_ip_checksum(ipr,
-                                       IP_HDR_SIZE);
-
-                               icmpr->type = ICMP_ECHO_REPLY;
-                               icmpr->checksum = 0;
-                               icmpr->checksum = compute_ip_checksum(icmpr,
-                                       ICMP_HDR_SIZE);
-
-                               priv->recv_packet_length = length;
-                       }
-               }
+       return 0;
+}
+
+/*
+ * sandbox_eth_set_tx_handler()
+ *
+ * Set a custom response to a packet being sent through the sandbox eth test
+ *     driver
+ *
+ * index - interface to set the handler for
+ * handler - The func ptr to call on send. If NULL, set to default handler
+ */
+void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler)
+{
+       struct udevice *dev;
+       struct eth_sandbox_priv *priv;
+       int ret;
+
+       ret = uclass_get_device(UCLASS_ETH, index, &dev);
+       if (ret)
+               return;
+
+       priv = dev_get_priv(dev);
+       if (handler)
+               priv->tx_handler = handler;
+       else
+               priv->tx_handler = sb_default_handler;
+}
+
+/*
+ * Set priv ptr
+ *
+ * priv - priv void ptr to store in the device
+ */
+void sandbox_eth_set_priv(int index, void *priv)
+{
+       struct udevice *dev;
+       struct eth_sandbox_priv *dev_priv;
+       int ret;
+
+       ret = uclass_get_device(UCLASS_ETH, index, &dev);
+       if (ret)
+               return;
+
+       dev_priv = dev_get_priv(dev);
+
+       dev_priv->priv = priv;
+}
+
+static int sb_eth_start(struct udevice *dev)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+       debug("eth_sandbox: Start\n");
+
+       priv->recv_packets = 0;
+       for (int i = 0; i < PKTBUFSRX; i++) {
+               priv->recv_packet_buffer[i] = net_rx_packets[i];
+               priv->recv_packet_length[i] = 0;
        }
 
        return 0;
 }
 
+static int sb_eth_send(struct udevice *dev, void *packet, int length)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+       debug("eth_sandbox: Send packet %d\n", length);
+
+       if (priv->disabled)
+               return 0;
+
+       return priv->tx_handler(dev, packet, length);
+}
+
 static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 {
        struct eth_sandbox_priv *priv = dev_get_priv(dev);
@@ -159,18 +354,37 @@ static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
                skip_timeout = false;
        }
 
-       if (priv->recv_packet_length) {
-               int lcl_recv_packet_length = priv->recv_packet_length;
+       if (priv->recv_packets) {
+               int lcl_recv_packet_length = priv->recv_packet_length[0];
 
-               debug("eth_sandbox: received packet %d\n",
-                     priv->recv_packet_length);
-               priv->recv_packet_length = 0;
-               *packetp = priv->recv_packet_buffer;
+               debug("eth_sandbox: received packet[%d], %d waiting\n",
+                     lcl_recv_packet_length, priv->recv_packets - 1);
+               *packetp = priv->recv_packet_buffer[0];
                return lcl_recv_packet_length;
        }
        return 0;
 }
 
+static int sb_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       int i;
+
+       if (!priv->recv_packets)
+               return 0;
+
+       --priv->recv_packets;
+       for (i = 0; i < priv->recv_packets; i++) {
+               priv->recv_packet_length[i] = priv->recv_packet_length[i + 1];
+               memcpy(priv->recv_packet_buffer[i],
+                      priv->recv_packet_buffer[i + 1],
+                      priv->recv_packet_length[i + 1]);
+       }
+       priv->recv_packet_length[priv->recv_packets] = 0;
+
+       return 0;
+}
+
 static void sb_eth_stop(struct udevice *dev)
 {
        debug("eth_sandbox: Stop\n");
@@ -189,6 +403,7 @@ static const struct eth_ops sb_eth_ops = {
        .start                  = sb_eth_start,
        .send                   = sb_eth_send,
        .recv                   = sb_eth_recv,
+       .free_pkt               = sb_eth_free_pkt,
        .stop                   = sb_eth_stop,
        .write_hwaddr           = sb_eth_write_hwaddr,
 };
@@ -212,6 +427,8 @@ static int sb_eth_ofdata_to_platdata(struct udevice *dev)
                return -EINVAL;
        }
        memcpy(priv->fake_host_hwaddr, mac, ARP_HLEN);
+       priv->disabled = false;
+       priv->tx_handler = sb_default_handler;
 
        return 0;
 }
index a822858..07fa5e3 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <dm.h>
+#include <dm/platform_data/spi_davinci.h>
 
 /* SPIGCR0 */
 #define SPIGCR0_SPIENA_MASK    0x1
@@ -529,50 +530,58 @@ static int davinci_spi_xfer(struct udevice *dev, unsigned int bitlen,
        return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
 }
 
+static const struct dm_spi_ops davinci_spi_ops = {
+       .claim_bus      = davinci_spi_claim_bus,
+       .release_bus    = davinci_spi_release_bus,
+       .xfer           = davinci_spi_xfer,
+       .set_speed      = davinci_spi_set_speed,
+       .set_mode       = davinci_spi_set_mode,
+};
+
 static int davinci_spi_probe(struct udevice *bus)
 {
-       /* Nothing to do */
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
+       struct davinci_spi_platdata *plat = bus->platdata;
+       ds->regs = plat->regs;
+       ds->num_cs = plat->num_cs;
+
        return 0;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 static int davinci_ofdata_to_platadata(struct udevice *bus)
 {
-       struct davinci_spi_slave *ds = dev_get_priv(bus);
-       const void *blob = gd->fdt_blob;
-       int node = dev_of_offset(bus);
+       struct davinci_spi_platdata *plat = bus->platdata;
+       fdt_addr_t addr;
 
-       ds->regs = devfdt_map_physmem(bus, sizeof(struct davinci_spi_regs));
-       if (!ds->regs) {
-               printf("%s: could not map device address\n", __func__);
+       addr = devfdt_get_addr(bus);
+       if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
-       }
-       ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
+       plat->regs = (struct davinci_spi_regs *)addr;
+       plat->num_cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), "num-cs", 4);
 
        return 0;
 }
 
-static const struct dm_spi_ops davinci_spi_ops = {
-       .claim_bus      = davinci_spi_claim_bus,
-       .release_bus    = davinci_spi_release_bus,
-       .xfer           = davinci_spi_xfer,
-       .set_speed      = davinci_spi_set_speed,
-       .set_mode       = davinci_spi_set_mode,
-};
-
 static const struct udevice_id davinci_spi_ids[] = {
        { .compatible = "ti,keystone-spi" },
        { .compatible = "ti,dm6441-spi" },
        { .compatible = "ti,da830-spi" },
        { }
 };
+#endif
 
 U_BOOT_DRIVER(davinci_spi) = {
        .name = "davinci_spi",
        .id = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
        .of_match = davinci_spi_ids,
-       .ops = &davinci_spi_ops,
        .ofdata_to_platdata = davinci_ofdata_to_platadata,
-       .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
+        .platdata_auto_alloc_size = sizeof(struct davinci_spi_platdata),
+#endif
        .probe = davinci_spi_probe,
+       .ops = &davinci_spi_ops,
+       .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
 };
 #endif
index d1b1047..7af610b 100644 (file)
@@ -94,7 +94,7 @@
 #define LAN7X_MAC_RX_MAX_SIZE(mtu) \
        ((mtu) << 16)                   /* Max frame size */
 #define LAN7X_MAC_RX_MAX_SIZE_DEFAULT \
-       LAN7X_MAC_RX_MAX_SIZE(ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */)
+       LAN7X_MAC_RX_MAX_SIZE(PKTSIZE_ALIGN + 4 /* VLAN */ + 4 /* CRC */)
 
 /* Timeouts */
 #define USB_CTRL_SET_TIMEOUT_MS                5000
index 8ab9b9f..90ef1f0 100644 (file)
@@ -71,11 +71,6 @@ unsigned packet_received, packet_sent;
  * RNDIS specs are ambiguous and appear to be incomplete, and are also
  * needlessly complex.  They borrow more from CDC ACM than CDC ECM.
  */
-#define ETH_ALEN       6               /* Octets in one ethernet addr   */
-#define ETH_HLEN       14              /* Total octets in header.       */
-#define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN   1500            /* Max. octets in payload        */
-#define ETH_FRAME_LEN  PKTSIZE_ALIGN   /* Max. octets in frame sans FCS */
 
 #define DRIVER_DESC            "Ethernet Gadget"
 /* Based on linux 2.6.27 version */
@@ -529,7 +524,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
        /* this descriptor actually adds value, surprise! */
        .iMACAddress =          STRING_ETHADDR,
        .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
-       .wMaxSegmentSize =      __constant_cpu_to_le16(ETH_FRAME_LEN),
+       .wMaxSegmentSize =      __constant_cpu_to_le16(PKTSIZE_ALIGN),
        .wNumberMCFilters =     __constant_cpu_to_le16(0),
        .bNumberPowerFilters =  0,
 };
@@ -1575,7 +1570,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
                        req->length -= length;
                        req->actual -= length;
                }
-               if (req->actual < ETH_HLEN || ETH_FRAME_LEN < req->actual) {
+               if (req->actual < ETH_HLEN || PKTSIZE_ALIGN < req->actual) {
 length_err:
                        dev->stats.rx_errors++;
                        dev->stats.rx_length_errors++;
index d47e29e..eec639f 100644 (file)
 
 #include "rndis.h"
 
-#define ETH_ALEN       6               /* Octets in one ethernet addr   */
-#define ETH_HLEN       14              /* Total octets in header.       */
-#define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN   1500            /* Max. octets in payload        */
-#define ETH_FRAME_LEN  PKTSIZE_ALIGN   /* Max. octets in frame sans FCS */
-
 /*
  * The driver for your USB chip needs to support ep0 OUT to work with
  * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
index 319f6aa..e685db1 100644 (file)
@@ -23,8 +23,6 @@
 * DM support in SPL
 */
 #ifdef CONFIG_SPL_BUILD
-#undef CONFIG_DM_SPI
-#undef CONFIG_DM_SPI_FLASH
 #undef CONFIG_DM_I2C
 #undef CONFIG_DM_I2C_COMPAT
 #endif
 
 #if !CONFIG_IS_ENABLED(DM_SERIAL)
 #define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE    -4      /* NS16550 register size */
 #define CONFIG_SYS_NS16550_COM1        DAVINCI_UART2_BASE /* Base address of UART2 */
 #endif
 #define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID)
diff --git a/include/dm/platform_data/spi_davinci.h b/include/dm/platform_data/spi_davinci.h
new file mode 100644 (file)
index 0000000..fbc62c2
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __spi_davinci_h
+#define __spi_davinci_h
+
+struct davinci_spi_platdata {
+       struct davinci_spi_regs *regs;
+       u8 num_cs;         /* total no. of CS available */
+};
+
+#endif /* __spi_davinci_h */
index b8e5df6..85d08f6 100644 (file)
 #define DP83867_RGMIIDCTL_3_75_NS      0xe
 #define DP83867_RGMIIDCTL_4_00_NS      0xf
 
+/* IO_MUX_CFG - Clock output selection */
+#define DP83867_CLK_O_SEL_CHN_A_RCLK           0x0
+#define DP83867_CLK_O_SEL_CHN_B_RCLK           0x1
+#define DP83867_CLK_O_SEL_CHN_C_RCLK           0x2
+#define DP83867_CLK_O_SEL_CHN_D_RCLK           0x3
+#define DP83867_CLK_O_SEL_CHN_A_RCLK_DIV5      0x4
+#define DP83867_CLK_O_SEL_CHN_B_RCLK_DIV5      0x5
+#define DP83867_CLK_O_SEL_CHN_C_RCLK_DIV5      0x6
+#define DP83867_CLK_O_SEL_CHN_D_RCLK_DIV5      0x7
+#define DP83867_CLK_O_SEL_CHN_A_TCLK           0x8
+#define DP83867_CLK_O_SEL_CHN_B_TCLK           0x9
+#define DP83867_CLK_O_SEL_CHN_C_TCLK           0xA
+#define DP83867_CLK_O_SEL_CHN_D_TCLK           0xB
+#define DP83867_CLK_O_SEL_REF_CLK              0xC
+
 #endif
index 07e5130..b55c39c 100644 (file)
@@ -6,7 +6,11 @@
 #ifndef __LDPAA_WRIOP_H
 #define __LDPAA_WRIOP_H
 
- #include <phy.h>
+#include <phy.h>
+
+#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0"
+#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1"
+#define WRIOP_MAX_PHY_NUM        2
 
 enum wriop_port {
        WRIOP1_DPMAC1 = 1,
@@ -40,34 +44,30 @@ struct wriop_dpmac_info {
        u8 enabled;
        u8 id;
        u8 board_mux;
-       int phy_addr;
-       void *phy_regs;
+       int phy_addr[WRIOP_MAX_PHY_NUM];
        phy_interface_t enet_if;
-       struct phy_device *phydev;
+       struct phy_device *phydev[WRIOP_MAX_PHY_NUM];
        struct mii_dev *bus;
 };
 
 extern struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS];
 
-#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0"
-#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1"
-
-void wriop_init_dpmac(int, int, int);
-void wriop_disable_dpmac(int);
-void wriop_enable_dpmac(int);
-u8 wriop_is_enabled_dpmac(int dpmac_id);
-void wriop_set_mdio(int, struct mii_dev *);
-struct mii_dev *wriop_get_mdio(int);
-void wriop_set_phy_address(int, int);
-int wriop_get_phy_address(int);
-void wriop_set_phy_dev(int, struct phy_device *);
-struct phy_device *wriop_get_phy_dev(int);
-phy_interface_t wriop_get_enet_if(int);
+void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl);
+void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if);
+int wriop_disable_dpmac(int dpmac_id);
+int wriop_enable_dpmac(int dpmac_id);
+int wriop_is_enabled_dpmac(int dpmac_id);
+int wriop_set_mdio(int dpmac_id, struct mii_dev *bus);
+struct mii_dev *wriop_get_mdio(int dpmac_id);
+int wriop_set_phy_address(int dpmac_id, int phy_num, int address);
+int wriop_get_phy_address(int dpmac_id, int phy_num);
+int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev);
+struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num);
+phy_interface_t wriop_get_enet_if(int dpmac_id);
 
-void wriop_dpmac_disable(int);
-void wriop_dpmac_enable(int);
-phy_interface_t wriop_dpmac_enet_if(int, int);
-void wriop_init_dpmac_qsgmii(int, int);
+void wriop_dpmac_disable(int dpmac_id);
+void wriop_dpmac_enable(int dpmac_id);
+phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl);
+void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl);
 void wriop_init_rgmii(void);
-void wriop_init_dpmac_enet_if(int , phy_interface_t);
 #endif /* __LDPAA_WRIOP_H */
index 6e3feb6..d0f51ba 100644 (file)
@@ -43,6 +43,25 @@ extern struct p_current *current;
 #define dev_warn(dev, fmt, args...)            \
        printf(fmt, ##args)
 
+#define netdev_emerg(dev, fmt, args...)                \
+       printf(fmt, ##args)
+#define netdev_alert(dev, fmt, args...)                \
+       printf(fmt, ##args)
+#define netdev_crit(dev, fmt, args...)         \
+       printf(fmt, ##args)
+#define netdev_err(dev, fmt, args...)          \
+       printf(fmt, ##args)
+#define netdev_warn(dev, fmt, args...)         \
+       printf(fmt, ##args)
+#define netdev_notice(dev, fmt, args...)       \
+       printf(fmt, ##args)
+#define netdev_info(dev, fmt, args...)         \
+       printf(fmt, ##args)
+#define netdev_dbg(dev, fmt, args...)          \
+       debug(fmt, ##args)
+#define netdev_vdbg(dev, fmt, args...)         \
+       debug(fmt, ##args)
+
 #define GFP_ATOMIC ((gfp_t) 0)
 #define GFP_KERNEL ((gfp_t) 0)
 #define GFP_NOFS ((gfp_t) 0)
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
new file mode 100644 (file)
index 0000000..0d62aef
--- /dev/null
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Global definitions for the Ethernet IEEE 802.3 interface.
+ *
+ * Version:    @(#)if_ether.h  1.0.1a  02/08/94
+ *
+ * Author:     Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *             Donald Becker, <becker@super.org>
+ *             Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *             Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ *
+ *             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; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_LINUX_IF_ETHER_H
+#define _UAPI_LINUX_IF_ETHER_H
+
+#include <linux/types.h>
+
+/*
+ *     IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
+ *     and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN       6       /* Octets in one ethernet addr   */
+#define ETH_TLEN       2       /* Octets in ethernet type field */
+#define ETH_HLEN       14      /* Total octets in header.       */
+#define ETH_ZLEN       60      /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN   1500    /* Max. octets in payload        */
+#define ETH_FRAME_LEN  1514    /* Max. octets in frame sans FCS */
+#define ETH_FCS_LEN    4       /* Octets in the FCS             */
+
+#define ETH_MIN_MTU    68      /* Min IPv4 MTU per RFC791       */
+#define ETH_MAX_MTU    0xFFFFU /* 65535, same as IP_MAX_MTU     */
+
+/*
+ *     These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP     0x0060  /* Ethernet Loopback packet     */
+#define ETH_P_PUP      0x0200  /* Xerox PUP packet             */
+#define ETH_P_PUPAT    0x0201  /* Xerox PUP Addr Trans packet  */
+#define ETH_P_TSN      0x22F0  /* TSN (IEEE 1722) packet       */
+#define ETH_P_ERSPAN2  0x22EB  /* ERSPAN version 2 (type III)  */
+#define ETH_P_IP       0x0800  /* Internet Protocol packet     */
+#define ETH_P_X25      0x0805  /* CCITT X.25                   */
+#define ETH_P_ARP      0x0806  /* Address Resolution packet    */
+#define ETH_P_BPQ      0x08FF  /* G8BPQ AX.25 Ethernet Packet  */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IEEEPUP  0x0a00  /* Xerox IEEE802.3 PUP packet   */
+#define ETH_P_IEEEPUPAT        0x0a01  /* Xerox IEEE802.3 PUP Addr Trans packet */
+#define ETH_P_BATMAN   0x4305  /* B.A.T.M.A.N.-Advanced packet */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DEC      0x6000  /* DEC Assigned proto           */
+#define ETH_P_DNA_DL   0x6001  /* DEC DNA Dump/Load            */
+#define ETH_P_DNA_RC   0x6002  /* DEC DNA Remote Console       */
+#define ETH_P_DNA_RT   0x6003  /* DEC DNA Routing              */
+#define ETH_P_LAT      0x6004  /* DEC LAT                      */
+#define ETH_P_DIAG     0x6005  /* DEC Diagnostics              */
+#define ETH_P_CUST     0x6006  /* DEC Customer use             */
+#define ETH_P_SCA      0x6007  /* DEC Systems Comms Arch       */
+#define ETH_P_TEB      0x6558  /* Trans Ether Bridging         */
+#define ETH_P_RARP     0x8035  /* Reverse Addr Res packet      */
+#define ETH_P_ATALK    0x809B  /* Appletalk DDP                */
+#define ETH_P_AARP     0x80F3  /* Appletalk AARP               */
+#define ETH_P_8021Q    0x8100  /* 802.1Q VLAN Extended Header  */
+#define ETH_P_ERSPAN   0x88BE  /* ERSPAN type II               */
+#define ETH_P_IPX      0x8137  /* IPX over DIX                 */
+#define ETH_P_IPV6     0x86DD  /* IPv6 over bluebook           */
+#define ETH_P_PAUSE    0x8808  /* IEEE Pause frames. See 802.3 31B */
+#define ETH_P_SLOW     0x8809  /* Slow Protocol. See 802.3ad 43B */
+#define ETH_P_WCCP     0x883E  /* Web-cache coordination */
+                               /* protocol defined in */
+                               /* draft-wilson-wrec-wccp-v2-00.txt */
+#define ETH_P_MPLS_UC  0x8847  /* MPLS Unicast traffic         */
+#define ETH_P_MPLS_MC  0x8848  /* MPLS Multicast traffic       */
+#define ETH_P_ATMMPOA  0x884c  /* MultiProtocol Over ATM       */
+#define ETH_P_PPP_DISC 0x8863  /* PPPoE discovery messages     */
+#define ETH_P_PPP_SES  0x8864  /* PPPoE session messages       */
+#define ETH_P_LINK_CTL 0x886c  /* HPNA, wlan link local tunnel */
+#define ETH_P_ATMFATE  0x8884  /* Frame-based ATM Transport over Ethernet */
+#define ETH_P_PAE      0x888E  /* Port Access Entity (IEEE 802.1X) */
+#define ETH_P_AOE      0x88A2  /* ATA over Ethernet            */
+#define ETH_P_8021AD   0x88A8  /* 802.1ad Service VLAN         */
+#define ETH_P_802_EX1  0x88B5  /* 802.1 Local Experimental 1.  */
+#define ETH_P_PREAUTH  0x88C7  /* 802.11 Preauthentication     */
+#define ETH_P_TIPC     0x88CA  /* TIPC                         */
+#define ETH_P_MACSEC   0x88E5  /* 802.1ae MACsec               */
+#define ETH_P_8021AH   0x88E7  /* 802.1ah Backbone Service Tag */
+#define ETH_P_MVRP     0x88F5  /* 802.1Q MVRP                  */
+#define ETH_P_1588     0x88F7  /* IEEE 1588 Timesync           */
+#define ETH_P_NCSI     0x88F8  /* NCSI protocol                */
+#define ETH_P_PRP      0x88FB  /* IEC 62439-3 PRP/HSRv0        */
+#define ETH_P_FCOE     0x8906  /* Fibre Channel over Ethernet  */
+#define ETH_P_IBOE     0x8915  /* Infiniband over Ethernet     */
+#define ETH_P_TDLS     0x890D  /* TDLS                         */
+#define ETH_P_FIP      0x8914  /* FCoE Initialization Protocol */
+#define ETH_P_80221    0x8917  /* IEEE 802.21 Media Independent */
+                               /* Handover Protocol            */
+#define ETH_P_HSR      0x892F  /* IEC 62439-3 HSRv1            */
+#define ETH_P_NSH      0x894F  /* Network Service Header       */
+#define ETH_P_LOOPBACK 0x9000  /* Ethernet loopback packet, per IEEE 802.3 */
+#define ETH_P_QINQ1    0x9100  /* deprecated QinQ VLAN         */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ2    0x9200  /* deprecated QinQ VLAN         */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ3    0x9300  /* deprecated QinQ VLAN]        */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_EDSA     0xDADA  /* Ethertype DSA                */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IFE      0xED3E  /* ForCES inter-FE LFB type     */
+#define ETH_P_AF_IUCV   0xFBFB /* IBM af_iucv                  */
+                               /* [ NOT AN OFFICIALLY REGISTERED ID ] */
+
+#define ETH_P_802_3_MIN        0x0600  /* If the value in the ethernet type is less */
+                               /* than this value then the frame is Ethernet */
+                               /* II. Else it is 802.3 */
+
+/*
+ *     Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3    0x0001  /* Dummy type for 802.3 frames  */
+#define ETH_P_AX25     0x0002  /* Dummy protocol id for AX.25  */
+#define ETH_P_ALL      0x0003  /* Every packet (be careful!!!) */
+#define ETH_P_802_2    0x0004  /* 802.2 frames                 */
+#define ETH_P_SNAP     0x0005  /* Internal only                */
+#define ETH_P_DDCMP    0x0006  /* DEC DDCMP: Internal only     */
+#define ETH_P_WAN_PPP  0x0007  /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP   0x0008  /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK        0x0009  /* Localtalk pseudo type        */
+#define ETH_P_CAN      0x000C  /* CAN: Controller Area Network */
+#define ETH_P_CANFD    0x000D  /* CANFD: CAN flexible data rate*/
+#define ETH_P_PPPTALK  0x0010  /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011  /* 802.2 frames                 */
+#define ETH_P_MOBITEX  0x0015  /* Mobitex (kaz@cafe.net)       */
+#define ETH_P_CONTROL  0x0016  /* Card specific control frames */
+#define ETH_P_IRDA     0x0017  /* Linux-IrDA                   */
+#define ETH_P_ECONET   0x0018  /* Acorn Econet                 */
+#define ETH_P_HDLC     0x0019  /* HDLC frames                  */
+#define ETH_P_ARCNET   0x001A  /* 1A for ArcNet :-)            */
+#define ETH_P_DSA      0x001B  /* Distributed Switch Arch      */
+#define ETH_P_TRAILER  0x001C  /* Trailer switch tagging       */
+#define ETH_P_PHONET   0x00F5  /* Nokia Phonet frames          */
+#define ETH_P_IEEE802154 0x00F6        /* IEEE802.15.4 frame           */
+#define ETH_P_CAIF     0x00F7  /* ST-Ericsson CAIF protocol    */
+#define ETH_P_XDSA     0x00F8  /* Multiplexed DSA protocol     */
+#define ETH_P_MAP      0x00F9  /* Qualcomm multiplexing and    */
+                               /* aggregation protocol         */
+
+/* The following macros come from Linux kernel include/linux/if_vlan.h */
+
+#define VLAN_HLEN      4       /* The additional bytes required by VLAN */
+                               /* (in addition to the Ethernet header)  */
+#define VLAN_ETH_HLEN  18      /* Total octets in header.               */
+#define VLAN_ETH_ZLEN  64      /* Min. octets in frame sans FCS         */
+
+/*
+ * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
+ */
+#define VLAN_ETH_DATA_LEN      1500    /* Max. octets in payload        */
+#define VLAN_ETH_FRAME_LEN     1518    /* Max. octets in frame sans FCS */
+
+#define VLAN_PRIO_MASK         0xe000  /* Priority Code Point           */
+#define VLAN_PRIO_SHIFT                13
+#define VLAN_CFI_MASK          0x1000  /* Canonical Format Indicator    */
+#define VLAN_TAG_PRESENT       VLAN_CFI_MASK
+#define VLAN_VID_MASK          0x0fff  /* VLAN Identifier               */
+#define VLAN_N_VID             4096
+
+#endif /* _UAPI_LINUX_IF_ETHER_H */
index ea20608..6e821d9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * linux/mdio.h: definitions for MDIO (clause 45) transceivers
  * Copyright 2006-2009 Solarflare Communications Inc.
 #define MDIO_PKGID2            15
 #define MDIO_AN_ADVERTISE      16      /* AN advertising (base page) */
 #define MDIO_AN_LPA            19      /* AN LP abilities (base page) */
+#define MDIO_PCS_EEE_ABLE      20      /* EEE Capability register */
+#define MDIO_PCS_EEE_WK_ERR    22      /* EEE wake error counter */
 #define MDIO_PHYXS_LNSTAT      24      /* PHY XGXS lane state */
+#define MDIO_AN_EEE_ADV                60      /* EEE advertisement */
+#define MDIO_AN_EEE_LPABLE     61      /* EEE link partner ability */
 
 /* Media-dependent registers. */
 #define MDIO_PMA_10GBT_SWAPPOL 130     /* 10GBASE-T pair swap & polarity */
@@ -55,7 +60,6 @@
 #define MDIO_PCS_10GBRT_STAT2  33      /* 10GBASE-R/-T PCS status 2 */
 #define MDIO_AN_10GBT_CTRL     32      /* 10GBASE-T auto-negotiation control */
 #define MDIO_AN_10GBT_STAT     33      /* 10GBASE-T auto-negotiation status */
-#define MDIO_AN_EEE_ADV                60      /* EEE advertisement */
 
 /* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
 #define MDIO_PMA_LASI_RXCTRL   0x9000  /* RX_ALARM control */
@@ -81,6 +85,7 @@
 #define MDIO_AN_CTRL1_RESTART          BMCR_ANRESTART
 #define MDIO_AN_CTRL1_ENABLE           BMCR_ANENABLE
 #define MDIO_AN_CTRL1_XNP              0x2000  /* Enable extended next page */
+#define MDIO_PCS_CTRL1_CLKSTOP_EN      0x400   /* Stop the clock during LPI */
 
 /* 10 Gb/s */
 #define MDIO_CTRL1_SPEED10G            (MDIO_CTRL1_SPEEDSELEXT | 0x00)
 #define MDIO_AN_10GBT_STAT_MS          0x4000  /* Master/slave config */
 #define MDIO_AN_10GBT_STAT_MSFLT       0x8000  /* Master/slave config fault */
 
-/* AN EEE Advertisement register. */
-#define MDIO_AN_EEE_ADV_100TX          0x0002  /* Advertise 100TX EEE cap */
-#define MDIO_AN_EEE_ADV_1000T          0x0004  /* Advertise 1000T EEE cap */
+/* EEE Supported/Advertisement/LP Advertisement registers.
+ *
+ * EEE capability Register (3.20), Advertisement (7.60) and
+ * Link partner ability (7.61) registers have and can use the same identical
+ * bit masks.
+ */
+#define MDIO_AN_EEE_ADV_100TX  0x0002  /* Advertise 100TX EEE cap */
+#define MDIO_AN_EEE_ADV_1000T  0x0004  /* Advertise 1000T EEE cap */
+/* Note: the two defines above can be potentially used by the user-land
+ * and cannot remove them now.
+ * So, we define the new generic MDIO_EEE_100TX and MDIO_EEE_1000T macros
+ * using the previous ones (that can be considered obsolete).
+ */
+#define MDIO_EEE_100TX         MDIO_AN_EEE_ADV_100TX   /* 100TX EEE cap */
+#define MDIO_EEE_1000T         MDIO_AN_EEE_ADV_1000T   /* 1000T EEE cap */
+#define MDIO_EEE_10GT          0x0008  /* 10GT EEE cap */
+#define MDIO_EEE_1000KX                0x0010  /* 1000KX EEE cap */
+#define MDIO_EEE_10GKX4                0x0020  /* 10G KX4 EEE cap */
+#define MDIO_EEE_10GKR         0x0040  /* 10G KR EEE cap */
 
 /* LASI RX_ALARM control/status registers. */
 #define MDIO_PMA_LASI_RX_PHYXSLFLT     0x0001  /* PHY XS RX local fault */
 #define MDIO_DEVAD_NONE                        (-1)
 #define MDIO_EMULATE_C22               4
 
+static inline __u16 mdio_phy_id_c45(int prtad, int devad)
+{
+       return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
+}
+
 #endif /* __LINUX_MDIO_H__ */
index 19afb74..21db032 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * linux/mii.h: definitions for MII-compatible transceivers
  * Originally drivers/net/sunhme.h.
 #define __LINUX_MII_H__
 
 /* Generic MII registers. */
-
-#define MII_BMCR           0x00        /* Basic mode control register */
-#define MII_BMSR           0x01        /* Basic mode status register  */
-#define MII_PHYSID1        0x02        /* PHYS ID 1                   */
-#define MII_PHYSID2        0x03        /* PHYS ID 2                   */
-#define MII_ADVERTISE      0x04        /* Advertisement control reg   */
-#define MII_LPA                    0x05        /* Link partner ability reg    */
-#define MII_EXPANSION      0x06        /* Expansion register          */
-#define MII_CTRL1000       0x09        /* 1000BASE-T control          */
-#define MII_STAT1000       0x0a        /* 1000BASE-T status           */
-#define MII_ESTATUS        0x0f        /* Extended Status */
-#define MII_DCOUNTER       0x12        /* Disconnect counter          */
-#define MII_FCSCOUNTER     0x13        /* False carrier counter       */
-#define MII_NWAYTEST       0x14        /* N-way auto-neg test reg     */
-#define MII_RERRCOUNTER     0x15       /* Receive error counter       */
-#define MII_SREVISION      0x16        /* Silicon revision            */
-#define MII_RESV1          0x17        /* Reserved...                 */
-#define MII_LBRERROR       0x18        /* Lpback, rx, bypass error    */
-#define MII_PHYADDR        0x19        /* PHY address                 */
-#define MII_RESV2          0x1a        /* Reserved...                 */
-#define MII_TPISTATUS      0x1b        /* TPI status for 10mbps       */
-#define MII_NCONFIG        0x1c        /* Network interface config    */
+#define MII_BMCR               0x00    /* Basic mode control register */
+#define MII_BMSR               0x01    /* Basic mode status register  */
+#define MII_PHYSID1            0x02    /* PHYS ID 1                   */
+#define MII_PHYSID2            0x03    /* PHYS ID 2                   */
+#define MII_ADVERTISE          0x04    /* Advertisement control reg   */
+#define MII_LPA                        0x05    /* Link partner ability reg    */
+#define MII_EXPANSION          0x06    /* Expansion register          */
+#define MII_CTRL1000           0x09    /* 1000BASE-T control          */
+#define MII_STAT1000           0x0a    /* 1000BASE-T status           */
+#define MII_MMD_CTRL           0x0d    /* MMD Access Control Register */
+#define MII_MMD_DATA           0x0e    /* MMD Access Data Register */
+#define MII_ESTATUS            0x0f    /* Extended Status             */
+#define MII_DCOUNTER           0x12    /* Disconnect counter          */
+#define MII_FCSCOUNTER         0x13    /* False carrier counter       */
+#define MII_NWAYTEST           0x14    /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER                0x15    /* Receive error counter       */
+#define MII_SREVISION          0x16    /* Silicon revision            */
+#define MII_RESV1              0x17    /* Reserved...                 */
+#define MII_LBRERROR           0x18    /* Lpback, rx, bypass error    */
+#define MII_PHYADDR            0x19    /* PHY address                 */
+#define MII_RESV2              0x1a    /* Reserved...                 */
+#define MII_TPISTATUS          0x1b    /* TPI status for 10mbps       */
+#define MII_NCONFIG            0x1c    /* Network interface config    */
 
 /* Basic mode control register. */
-#define BMCR_RESV              0x003f  /* Unused...                   */
-#define BMCR_SPEED1000         0x0040  /* MSB of Speed (1000)         */
-#define BMCR_CTST              0x0080  /* Collision test              */
-#define BMCR_FULLDPLX          0x0100  /* Full duplex                 */
+#define BMCR_RESV              0x003f  /* Unused...                   */
+#define BMCR_SPEED1000         0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST              0x0080  /* Collision test              */
+#define BMCR_FULLDPLX          0x0100  /* Full duplex                 */
 #define BMCR_ANRESTART         0x0200  /* Auto negotiation restart    */
-#define BMCR_ISOLATE           0x0400  /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN             0x0800  /* Powerdown the DP83840       */
+#define BMCR_ISOLATE           0x0400  /* Isolate data paths from MII */
+#define BMCR_PDOWN             0x0800  /* Enable low power state      */
 #define BMCR_ANENABLE          0x1000  /* Enable auto negotiation     */
-#define BMCR_SPEED100          0x2000  /* Select 100Mbps              */
-#define BMCR_LOOPBACK          0x4000  /* TXD loopback bits           */
-#define BMCR_RESET             0x8000  /* Reset the DP83840           */
+#define BMCR_SPEED100          0x2000  /* Select 100Mbps              */
+#define BMCR_LOOPBACK          0x4000  /* TXD loopback bits           */
+#define BMCR_RESET             0x8000  /* Reset to default state      */
+#define BMCR_SPEED10           0x0000  /* Select 10Mbps               */
 
 /* Basic mode status register. */
-#define BMSR_ERCAP             0x0001  /* Ext-reg capability          */
-#define BMSR_JCD               0x0002  /* Jabber detected             */
-#define BMSR_LSTATUS           0x0004  /* Link status                 */
+#define BMSR_ERCAP             0x0001  /* Ext-reg capability          */
+#define BMSR_JCD               0x0002  /* Jabber detected             */
+#define BMSR_LSTATUS           0x0004  /* Link status                 */
 #define BMSR_ANEGCAPABLE       0x0008  /* Able to do auto-negotiation */
 #define BMSR_RFAULT            0x0010  /* Remote fault detected       */
 #define BMSR_ANEGCOMPLETE      0x0020  /* Auto-negotiation complete   */
-#define BMSR_RESV              0x00c0  /* Unused...                   */
-#define BMSR_ESTATEN           0x0100  /* Extended Status in R15 */
-#define BMSR_100HALF2          0x0200  /* Can do 100BASE-T2 HDX */
-#define BMSR_100FULL2          0x0400  /* Can do 100BASE-T2 FDX */
+#define BMSR_RESV              0x00c0  /* Unused...                   */
+#define BMSR_ESTATEN           0x0100  /* Extended Status in R15      */
+#define BMSR_100HALF2          0x0200  /* Can do 100BASE-T2 HDX       */
+#define BMSR_100FULL2          0x0400  /* Can do 100BASE-T2 FDX       */
 #define BMSR_10HALF            0x0800  /* Can do 10mbps, half-duplex  */
 #define BMSR_10FULL            0x1000  /* Can do 10mbps, full-duplex  */
 #define BMSR_100HALF           0x2000  /* Can do 100mbps, half-duplex */
@@ -63,7 +66,7 @@
 #define BMSR_100BASE4          0x8000  /* Can do 100mbps, 4k packets  */
 
 /* Advertisement control register. */
-#define ADVERTISE_SLCT         0x001f  /* Selector bits               */
+#define ADVERTISE_SLCT         0x001f  /* Selector bits               */
 #define ADVERTISE_CSMA         0x0001  /* Only selector supported     */
 #define ADVERTISE_10HALF       0x0020  /* Try for 10mbps half-duplex  */
 #define ADVERTISE_1000XFULL    0x0020  /* Try for 1000BASE-X full-duplex */
 #define ADVERTISE_100HALF      0x0080  /* Try for 100mbps half-duplex */
 #define ADVERTISE_1000XPAUSE   0x0080  /* Try for 1000BASE-X pause    */
 #define ADVERTISE_100FULL      0x0100  /* Try for 100mbps full-duplex */
-#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_1000XPSE_ASYM        0x0100  /* Try for 1000BASE-X asym pause */
 #define ADVERTISE_100BASE4     0x0200  /* Try for 100mbps 4k packets  */
-#define ADVERTISE_PAUSE_CAP    0x0400  /* Try for pause               */
+#define ADVERTISE_PAUSE_CAP    0x0400  /* Try for pause               */
 #define ADVERTISE_PAUSE_ASYM   0x0800  /* Try for asymetric pause     */
-#define ADVERTISE_RESV         0x1000  /* Unused...                   */
+#define ADVERTISE_RESV         0x1000  /* Unused...                   */
 #define ADVERTISE_RFAULT       0x2000  /* Say we can detect faults    */
 #define ADVERTISE_LPACK                0x4000  /* Ack link partners response  */
-#define ADVERTISE_NPAGE                0x8000  /* Next page bit               */
+#define ADVERTISE_NPAGE                0x8000  /* Next page bit               */
 
-#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
-                       ADVERTISE_CSMA)
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
-                      ADVERTISE_100HALF | ADVERTISE_100FULL)
+#define ADVERTISE_FULL         (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+                                ADVERTISE_CSMA)
+#define ADVERTISE_ALL          (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+                                ADVERTISE_100HALF | ADVERTISE_100FULL)
 
 /* Link partner ability register. */
 #define LPA_SLCT               0x001f  /* Same as advertise selector  */
 #define LPA_100FULL            0x0100  /* Can do 100mbps full-duplex  */
 #define LPA_1000XPAUSE_ASYM    0x0100  /* Can do 1000BASE-X pause asym*/
 #define LPA_100BASE4           0x0200  /* Can do 100mbps 4k packets   */
-#define LPA_PAUSE_CAP          0x0400  /* Can pause                   */
+#define LPA_PAUSE_CAP          0x0400  /* Can pause                   */
 #define LPA_PAUSE_ASYM         0x0800  /* Can pause asymetrically     */
-#define LPA_RESV               0x1000  /* Unused...                   */
+#define LPA_RESV               0x1000  /* Unused...                   */
 #define LPA_RFAULT             0x2000  /* Link partner faulted        */
 #define LPA_LPACK              0x4000  /* Link partner acked us       */
-#define LPA_NPAGE              0x8000  /* Next page bit               */
+#define LPA_NPAGE              0x8000  /* Next page bit               */
 
 #define LPA_DUPLEX             (LPA_10FULL | LPA_100FULL)
 #define LPA_100                        (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
 #define EXPANSION_ENABLENPAGE  0x0004  /* This enables npage words    */
 #define EXPANSION_NPCAPABLE    0x0008  /* Link partner supports npage */
 #define EXPANSION_MFAULTS      0x0010  /* Multiple faults detected    */
-#define EXPANSION_RESV         0xffe0  /* Unused...                   */
+#define EXPANSION_RESV         0xffe0  /* Unused...                   */
 
 #define ESTATUS_1000_XFULL     0x8000  /* Can do 1000BX Full */
 #define ESTATUS_1000_XHALF     0x4000  /* Can do 1000BX Half */
-#define ESTATUS_1000_TFULL     0x2000  /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF     0x1000  /* Can do 1000BT Half */
+#define ESTATUS_1000_TFULL     0x2000  /* Can do 1000BT Full          */
+#define ESTATUS_1000_THALF     0x1000  /* Can do 1000BT Half          */
 
 /* N-way test register. */
-#define NWAYTEST_RESV1         0x00ff  /* Unused...                   */
+#define NWAYTEST_RESV1         0x00ff  /* Unused...                   */
 #define NWAYTEST_LOOPBACK      0x0100  /* Enable loopback for N-way   */
-#define NWAYTEST_RESV2         0xfe00  /* Unused...                   */
+#define NWAYTEST_RESV2         0xfe00  /* Unused...                   */
 
 /* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL     0x0200  /* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF     0x0100  /* Advertise 1000BASE-T half duplex */
+#define ADVERTISE_1000FULL     0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF     0x0100  /* Advertise 1000BASE-T half duplex */
+#define CTL1000_AS_MASTER      0x0800
+#define CTL1000_ENABLE_MASTER  0x1000
 
 /* 1000BASE-T Status register */
 #define LPA_1000LOCALRXOK      0x2000  /* Link partner local receiver status */
 #define FLOW_CTRL_TX           0x01
 #define FLOW_CTRL_RX           0x02
 
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK        0x1f    /* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_ADDR      0x0000  /* Address */
+#define MII_MMD_CTRL_NOINCR    0x4000  /* no post increment */
+#define MII_MMD_CTRL_INCR_RDWT 0x8000  /* post increment on reads & writes */
+#define MII_MMD_CTRL_INCR_ON_WT        0xC000  /* post increment on writes only */
+
 /**
  * mii_nway_result
  * @negotiated: value of MII ANAR and'd with ANLPAR
index 2b2deb5..51c099d 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <asm/cache.h>
 #include <asm/byteorder.h>     /* for nton* / ntoh* stuff */
+#include <linux/if_ether.h>
 
 #define DEBUG_LL_STATE 0       /* Link local state machine changes */
 #define DEBUG_DEV_PKT 0                /* Packets or info directed to the device */
@@ -596,7 +597,8 @@ int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
 
 /* Set IP header */
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source);
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+                      u16 pkt_len, u8 proto);
 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
                                int sport, int len);
 
@@ -635,6 +637,7 @@ rxhand_f *net_get_udp_handler(void);        /* Get UDP RX packet handler */
 void net_set_udp_handler(rxhand_f *);  /* Set UDP RX packet handler */
 rxhand_f *net_get_arp_handler(void);   /* Get ARP RX packet handler */
 void net_set_arp_handler(rxhand_f *);  /* Set ARP RX packet handler */
+bool arp_is_waiting(void);             /* Waiting for ARP reply? */
 void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
 void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
 
@@ -653,6 +656,14 @@ static inline void net_set_state(enum net_loop_state state)
        net_state = state;
 }
 
+/*
+ * net_get_async_tx_pkt_buf - Get a packet buffer that is not in use for
+ *                           sending an asynchronous reply
+ *
+ * returns - ptr to packet buffer
+ */
+uchar * net_get_async_tx_pkt_buf(void);
+
 /* Transmit a packet */
 static inline void net_send_packet(uchar *pkt, int len)
 {
@@ -670,6 +681,9 @@ static inline void net_send_packet(uchar *pkt, int len)
  * @param sport Source UDP port
  * @param payload_len Length of data after the UDP header
  */
+int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
+                      int payload_len, int proto, u8 action, u32 tcp_seq_num,
+                      u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
                        int sport, int payload_len);
 
index 0760d65..c682318 100644 (file)
@@ -27,6 +27,10 @@ typedef enum {
        PHY_INTERFACE_MODE_RXAUI,
        PHY_INTERFACE_MODE_SFI,
        PHY_INTERFACE_MODE_INTERNAL,
+       PHY_INTERFACE_MODE_25G_AUI,
+       PHY_INTERFACE_MODE_XLAUI,
+       PHY_INTERFACE_MODE_CAUI2,
+       PHY_INTERFACE_MODE_CAUI4,
        PHY_INTERFACE_MODE_NONE,        /* Must be last */
 
        PHY_INTERFACE_MODE_COUNT,
@@ -50,6 +54,10 @@ static const char * const phy_interface_strings[] = {
        [PHY_INTERFACE_MODE_RXAUI]              = "rxaui",
        [PHY_INTERFACE_MODE_SFI]                = "sfi",
        [PHY_INTERFACE_MODE_INTERNAL]           = "internal",
+       [PHY_INTERFACE_MODE_25G_AUI]            = "25g-aui",
+       [PHY_INTERFACE_MODE_XLAUI]              = "xlaui4",
+       [PHY_INTERFACE_MODE_CAUI2]              = "caui2",
+       [PHY_INTERFACE_MODE_CAUI4]              = "caui4",
        [PHY_INTERFACE_MODE_NONE]               = "",
 };
 
index 49f47d3..e85acad 100644 (file)
@@ -8,16 +8,6 @@
 
 #include <net.h>
 
-/*
- *     IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
- *     and FCS/CRC (frame check sequence).
- */
-#define ETH_ALEN       6               /* Octets in one ethernet addr   */
-#define ETH_HLEN       14              /* Total octets in header.       */
-#define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN   1500            /* Max. octets in payload        */
-#define ETH_FRAME_LEN  PKTSIZE_ALIGN   /* Max. octets in frame sans FCS */
-
 /* TODO(sjg@chromium.org): Remove @pusb_dev when all boards use CONFIG_DM_ETH */
 struct ueth_data {
        /* eth info */
index b1b3925..a420ba1 100644 (file)
@@ -15,7 +15,6 @@
 #include <serial.h>
 #include <asm/sections.h>
 #include <linux/ctype.h>
-#include <linux/ioport.h>
 #include <linux/lzo.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -1099,34 +1098,41 @@ int fdtdec_setup_mem_size_base(void)
 
 #if defined(CONFIG_NR_DRAM_BANKS)
 
-static ofnode get_next_memory_node(ofnode mem)
+static int get_next_memory_node(const void *blob, int mem)
 {
        do {
-               mem = ofnode_by_prop_value(mem, "device_type", "memory", 7);
-       } while (ofnode_valid(mem) && !ofnode_is_available(mem));
+               mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
+                                                   "device_type", "memory", 7);
+       } while (!fdtdec_get_is_enabled(blob, mem));
 
        return mem;
 }
 
 int fdtdec_setup_memory_banksize(void)
 {
-       int bank, reg = 0;
-       struct resource res;
-       ofnode mem;
+       int bank, ret, mem, reg = 0;
+       struct fdt_resource res;
 
-       mem = get_next_memory_node(ofnode_null());
-       if (!ofnode_valid(mem))
-               goto missing_node;
+       mem = get_next_memory_node(gd->fdt_blob, -1);
+       if (mem < 0) {
+               debug("%s: Missing /memory node\n", __func__);
+               return -EINVAL;
+       }
 
        for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
-               while (ofnode_read_resource(mem, reg++, &res)) {
+               ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+               if (ret == -FDT_ERR_NOTFOUND) {
                        reg = 0;
-                       mem = get_next_memory_node(mem);
-                       if (!ofnode_valid(mem)) {
-                               if (bank)
-                                       return 0;
-                               goto missing_node;
-                       }
+                       mem = get_next_memory_node(gd->fdt_blob, mem);
+                       if (mem == -FDT_ERR_NOTFOUND)
+                               break;
+
+                       ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+                       if (ret == -FDT_ERR_NOTFOUND)
+                               break;
+               }
+               if (ret != 0) {
+                       return -EINVAL;
                }
 
                gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
@@ -1140,10 +1146,6 @@ int fdtdec_setup_memory_banksize(void)
        }
 
        return 0;
-
-missing_node:
-       debug("%s: Missing /memory node\n", __func__);
-       return -EINVAL;
 }
 #endif
 
index b8a7168..b49c3d3 100644 (file)
--- a/net/arp.c
+++ b/net/arp.c
@@ -34,8 +34,7 @@ uchar        *arp_wait_packet_ethaddr;
 int            arp_wait_tx_packet_size;
 ulong          arp_wait_timer_start;
 int            arp_wait_try;
-
-static uchar   *arp_tx_packet; /* THE ARP transmit packet */
+uchar         *arp_tx_packet; /* THE ARP transmit packet */
 static uchar   arp_tx_packet_buf[PKTSIZE_ALIGN + PKTALIGN];
 
 void arp_init(void)
@@ -100,7 +99,7 @@ int arp_timeout_check(void)
 {
        ulong t;
 
-       if (!net_arp_wait_packet_ip.s_addr)
+       if (!arp_is_waiting())
                return 0;
 
        t = get_timer(0);
@@ -126,6 +125,7 @@ void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
        struct arp_hdr *arp;
        struct in_addr reply_ip_addr;
        int eth_hdr_size;
+       uchar *tx_packet;
 
        /*
         * We have to deal with two types of ARP packets:
@@ -182,13 +182,14 @@ void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
                    (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr))
                        udelay(5000);
 #endif
-               memcpy(net_tx_packet, et, eth_hdr_size + ARP_HDR_SIZE);
-               net_send_packet(net_tx_packet, eth_hdr_size + ARP_HDR_SIZE);
+               tx_packet = net_get_async_tx_pkt_buf();
+               memcpy(tx_packet, et, eth_hdr_size + ARP_HDR_SIZE);
+               net_send_packet(tx_packet, eth_hdr_size + ARP_HDR_SIZE);
                return;
 
        case ARPOP_REPLY:               /* arp reply */
-               /* are we waiting for a reply */
-               if (!net_arp_wait_packet_ip.s_addr)
+               /* are we waiting for a reply? */
+               if (!arp_is_waiting())
                        break;
 
 #ifdef CONFIG_KEEP_SERVERADDR
@@ -233,3 +234,8 @@ void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
                return;
        }
 }
+
+bool arp_is_waiting(void)
+{
+       return !!net_arp_wait_packet_ip.s_addr;
+}
index afb8695..25b3c00 100644 (file)
--- a/net/arp.h
+++ b/net/arp.h
@@ -20,6 +20,7 @@ extern uchar *arp_wait_packet_ethaddr;
 extern int arp_wait_tx_packet_size;
 extern ulong arp_wait_timer_start;
 extern int arp_wait_try;
+extern uchar *arp_tx_packet;
 
 void arp_init(void);
 void arp_request(void);
index 31cf306..a5a216c 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -799,9 +799,25 @@ void net_set_timeout_handler(ulong iv, thand_f *f)
        }
 }
 
+uchar *net_get_async_tx_pkt_buf(void)
+{
+       if (arp_is_waiting())
+               return arp_tx_packet; /* If we are waiting, we already sent */
+       else
+               return net_tx_packet;
+}
+
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
                int payload_len)
 {
+       return net_send_ip_packet(ether, dest, dport, sport, payload_len,
+                                 IPPROTO_UDP, 0, 0, 0);
+}
+
+int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
+                      int payload_len, int proto, u8 action, u32 tcp_seq_num,
+                      u32 tcp_ack_num)
+{
        uchar *pkt;
        int eth_hdr_size;
        int pkt_hdr_size;
@@ -822,9 +838,16 @@ int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
        pkt = (uchar *)net_tx_packet;
 
        eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
-       pkt += eth_hdr_size;
-       net_set_udp_header(pkt, dest, dport, sport, payload_len);
-       pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
+
+       switch (proto) {
+       case IPPROTO_UDP:
+               net_set_udp_header(pkt + eth_hdr_size, dest, dport, sport,
+                                  payload_len);
+               pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        /* if MAC address was not discovered yet, do an ARP request */
        if (memcmp(ether, net_null_ethaddr, 6) == 0) {
@@ -1455,7 +1478,8 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
        }
 }
 
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+                      u16 pkt_len, u8 proto)
 {
        struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
 
@@ -1465,7 +1489,8 @@ void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
        /* IP_HDR_SIZE / 4 (not including UDP) */
        ip->ip_hl_v  = 0x45;
        ip->ip_tos   = 0;
-       ip->ip_len   = htons(IP_HDR_SIZE);
+       ip->ip_len   = htons(pkt_len);
+       ip->ip_p     = proto;
        ip->ip_id    = htons(net_ip_id++);
        ip->ip_off   = htons(IP_FLAGS_DFRAG);   /* Don't fragment */
        ip->ip_ttl   = 255;
@@ -1474,6 +1499,8 @@ void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
        net_copy_ip((void *)&ip->ip_src, &source);
        /* already in network byte order */
        net_copy_ip((void *)&ip->ip_dst, &dest);
+
+       ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
 }
 
 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
@@ -1489,10 +1516,8 @@ void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
        if (len & 1)
                pkt[IP_UDP_HDR_SIZE + len] = 0;
 
-       net_set_ip_header(pkt, dest, net_ip);
-       ip->ip_len   = htons(IP_UDP_HDR_SIZE + len);
-       ip->ip_p     = IPPROTO_UDP;
-       ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
+       net_set_ip_header(pkt, dest, net_ip, IP_UDP_HDR_SIZE + len,
+                         IPPROTO_UDP);
 
        ip->udp_src  = htons(sport);
        ip->udp_dst  = htons(dport);
index 3e5461a..633c942 100644 (file)
@@ -22,14 +22,9 @@ static void set_icmp_header(uchar *pkt, struct in_addr dest)
        /*
         *      Construct an IP and ICMP header.
         */
-       struct ip_hdr *ip = (struct ip_hdr *)pkt;
        struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
 
-       net_set_ip_header(pkt, dest, net_ip);
-
-       ip->ip_len   = htons(IP_ICMP_HDR_SIZE);
-       ip->ip_p     = IPPROTO_ICMP;
-       ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
+       net_set_ip_header(pkt, dest, net_ip, IP_ICMP_HDR_SIZE, IPPROTO_ICMP);
 
        icmp->type = ICMP_ECHO_REQUEST;
        icmp->code = 0;
@@ -84,6 +79,7 @@ void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
        struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
        struct in_addr src_ip;
        int eth_hdr_size;
+       uchar *tx_packet;
 
        switch (icmph->type) {
        case ICMP_ECHO_REPLY:
@@ -107,8 +103,10 @@ void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
                icmph->type = ICMP_ECHO_REPLY;
                icmph->checksum = 0;
                icmph->checksum = compute_ip_checksum(icmph, len - IP_HDR_SIZE);
-               memcpy(net_tx_packet, et, eth_hdr_size + len);
-               net_send_packet(net_tx_packet, eth_hdr_size + len);
+
+               tx_packet = net_get_async_tx_pkt_buf();
+               memcpy(tx_packet, et, eth_hdr_size + len);
+               net_send_packet(tx_packet, eth_hdr_size + len);
                return;
 /*     default:
                return;*/
index 1a7684a..850eabb 100644 (file)
@@ -258,3 +258,173 @@ static int dm_test_net_retry(struct unit_test_state *uts)
        return retval;
 }
 DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
+
+static int sb_check_arp_reply(struct udevice *dev, void *packet,
+                             unsigned int len)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth = packet;
+       struct arp_hdr *arp;
+       /* Used by all of the ut_assert macros */
+       struct unit_test_state *uts = priv->priv;
+
+       if (ntohs(eth->et_protlen) != PROT_ARP)
+               return 0;
+
+       arp = packet + ETHER_HDR_SIZE;
+
+       if (ntohs(arp->ar_op) != ARPOP_REPLY)
+               return 0;
+
+       /* This test would be worthless if we are not waiting */
+       ut_assert(arp_is_waiting());
+
+       /* Validate response */
+       ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0);
+       ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+       ut_assert(eth->et_protlen == htons(PROT_ARP));
+
+       ut_assert(arp->ar_hrd == htons(ARP_ETHER));
+       ut_assert(arp->ar_pro == htons(PROT_IP));
+       ut_assert(arp->ar_hln == ARP_HLEN);
+       ut_assert(arp->ar_pln == ARP_PLEN);
+       ut_assert(memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) == 0);
+       ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
+       ut_assert(memcmp(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+       ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
+                 string_to_ip("1.1.2.4").s_addr);
+
+       return 0;
+}
+
+static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
+                                    unsigned int len)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth = packet;
+       struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+       int ret;
+
+       /*
+        * If we are about to generate a reply to ARP, first inject a request
+        * from another host
+        */
+       if (ntohs(eth->et_protlen) == PROT_ARP &&
+           ntohs(arp->ar_op) == ARPOP_REQUEST) {
+               /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
+               priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
+
+               ret = sandbox_eth_recv_arp_req(dev);
+               if (ret)
+                       return ret;
+       }
+
+       sandbox_eth_arp_req_to_reply(dev, packet, len);
+       sandbox_eth_ping_req_to_reply(dev, packet, len);
+
+       return sb_check_arp_reply(dev, packet, len);
+}
+
+static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
+{
+       net_ping_ip = string_to_ip("1.1.2.2");
+
+       sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
+       /* Used by all of the ut_assert macros in the tx_handler */
+       sandbox_eth_set_priv(0, uts);
+
+       env_set("ethact", "eth@10002000");
+       ut_assertok(net_loop(PING));
+       ut_asserteq_str("eth@10002000", env_get("ethact"));
+
+       sandbox_eth_set_tx_handler(0, NULL);
+
+       return 0;
+}
+
+DM_TEST(dm_test_eth_async_arp_reply, DM_TESTF_SCAN_FDT);
+
+static int sb_check_ping_reply(struct udevice *dev, void *packet,
+                              unsigned int len)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth = packet;
+       struct ip_udp_hdr *ip;
+       struct icmp_hdr *icmp;
+       /* Used by all of the ut_assert macros */
+       struct unit_test_state *uts = priv->priv;
+
+       if (ntohs(eth->et_protlen) != PROT_IP)
+               return 0;
+
+       ip = packet + ETHER_HDR_SIZE;
+
+       if (ip->ip_p != IPPROTO_ICMP)
+               return 0;
+
+       icmp = (struct icmp_hdr *)&ip->udp_src;
+
+       if (icmp->type != ICMP_ECHO_REPLY)
+               return 0;
+
+       /* This test would be worthless if we are not waiting */
+       ut_assert(arp_is_waiting());
+
+       /* Validate response */
+       ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0);
+       ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+       ut_assert(eth->et_protlen == htons(PROT_IP));
+
+       ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
+       ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
+                 string_to_ip("1.1.2.4").s_addr);
+
+       return 0;
+}
+
+static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
+                                     unsigned int len)
+{
+       struct eth_sandbox_priv *priv = dev_get_priv(dev);
+       struct ethernet_hdr *eth = packet;
+       struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+       int ret;
+
+       /*
+        * If we are about to generate a reply to ARP, first inject a request
+        * from another host
+        */
+       if (ntohs(eth->et_protlen) == PROT_ARP &&
+           ntohs(arp->ar_op) == ARPOP_REQUEST) {
+               /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
+               priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
+
+               ret = sandbox_eth_recv_ping_req(dev);
+               if (ret)
+                       return ret;
+       }
+
+       sandbox_eth_arp_req_to_reply(dev, packet, len);
+       sandbox_eth_ping_req_to_reply(dev, packet, len);
+
+       return sb_check_ping_reply(dev, packet, len);
+}
+
+static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
+{
+       net_ping_ip = string_to_ip("1.1.2.2");
+
+       sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
+       /* Used by all of the ut_assert macros in the tx_handler */
+       sandbox_eth_set_priv(0, uts);
+
+       env_set("ethact", "eth@10002000");
+       ut_assertok(net_loop(PING));
+       ut_asserteq_str("eth@10002000", env_get("ethact"));
+
+       sandbox_eth_set_tx_handler(0, NULL);
+
+       return 0;
+}
+
+DM_TEST(dm_test_eth_async_ping_reply, DM_TESTF_SCAN_FDT);