aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini2018-10-11 15:28:32 -0400
committerTom Rini2018-10-11 15:28:32 -0400
commit0223462b373b975d970fa86e5e1a7eadd1d41820 (patch)
tree65f798468bfb9cdf3c4c2a99bd88df9108ccd4df
parent3d5ced9e22d32112a20f9dc0f5fb1f22ef088079 (diff)
parent1a048cd65645338069d591108031fa4ebe96d53f (diff)
Merge branch 'master' of git://git.denx.de/u-boot-net
-rw-r--r--arch/sandbox/include/asm/eth.h93
-rw-r--r--board/Synology/ds414/cmd_syno.c1
-rw-r--r--board/freescale/ls1088a/eth_ls1088aqds.c18
-rw-r--r--board/freescale/ls1088a/eth_ls1088ardb.c21
-rw-r--r--board/freescale/ls2080aqds/eth.c26
-rw-r--r--board/freescale/ls2080ardb/eth_ls2080rdb.c24
-rw-r--r--doc/device-tree-bindings/net/ti,dp83867.txt8
-rw-r--r--drivers/net/dc2114x.c1
-rw-r--r--drivers/net/eepro100.c2
-rw-r--r--drivers/net/fsl-mc/mc.c6
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c171
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.h1
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_wriop.c69
-rw-r--r--drivers/net/mvneta.c8
-rw-r--r--drivers/net/mvpp2.c13
-rw-r--r--drivers/net/natsemi.c1
-rw-r--r--drivers/net/ns8382x.c1
-rw-r--r--drivers/net/pch_gbe.c4
-rw-r--r--drivers/net/phy/ti.c93
-rw-r--r--drivers/net/rtl8139.c4
-rw-r--r--drivers/net/rtl8169.c4
-rw-r--r--drivers/net/sandbox.c417
-rw-r--r--drivers/usb/eth/lan7x.h2
-rw-r--r--drivers/usb/gadget/ether.c9
-rw-r--r--drivers/usb/gadget/rndis.c6
-rw-r--r--include/dt-bindings/net/ti-dp83867.h15
-rw-r--r--include/fsl-mc/ldpaa_wriop.h46
-rw-r--r--include/linux/compat.h19
-rw-r--r--include/linux/if_ether.h178
-rw-r--r--include/linux/mdio.h34
-rw-r--r--include/linux/mii.h126
-rw-r--r--include/net.h16
-rw-r--r--include/phy_interface.h8
-rw-r--r--include/usb_ether.h10
-rw-r--r--net/arp.c20
-rw-r--r--net/arp.h1
-rw-r--r--net/net.c43
-rw-r--r--net/ping.c14
-rw-r--r--test/dm/eth.c170
39 files changed, 1294 insertions, 409 deletions
diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h
index bfcd11b593e..477fa00fad8 100644
--- a/arch/sandbox/include/asm/eth.h
+++ b/arch/sandbox/include/asm/eth.h
@@ -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 */
diff --git a/board/Synology/ds414/cmd_syno.c b/board/Synology/ds414/cmd_syno.c
index 34643ff538a..59e6fe03102 100644
--- a/board/Synology/ds414/cmd_syno.c
+++ b/board/Synology/ds414/cmd_syno.c
@@ -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="
diff --git a/board/freescale/ls1088a/eth_ls1088aqds.c b/board/freescale/ls1088a/eth_ls1088aqds.c
index 40b1a0e6310..f16b78cf03f 100644
--- a/board/freescale/ls1088a/eth_ls1088aqds.c
+++ b/board/freescale/ls1088a/eth_ls1088aqds.c
@@ -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);
diff --git a/board/freescale/ls1088a/eth_ls1088ardb.c b/board/freescale/ls1088a/eth_ls1088ardb.c
index 418f362e9a3..a2b52a879b1 100644
--- a/board/freescale/ls1088a/eth_ls1088ardb.c
+++ b/board/freescale/ls1088a/eth_ls1088ardb.c
@@ -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:
diff --git a/board/freescale/ls2080aqds/eth.c b/board/freescale/ls2080aqds/eth.c
index 989d57e09b1..f706fd4cb6a 100644
--- a/board/freescale/ls2080aqds/eth.c
+++ b/board/freescale/ls2080aqds/eth.c
@@ -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;
diff --git a/board/freescale/ls2080ardb/eth_ls2080rdb.c b/board/freescale/ls2080ardb/eth_ls2080rdb.c
index 45f1d603223..62c7a7a3155 100644
--- a/board/freescale/ls2080ardb/eth_ls2080rdb.c
+++ b/board/freescale/ls2080ardb/eth_ls2080rdb.c
@@ -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:
diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt
index cb77fdf0825..034146f5f80 100644
--- a/doc/device-tree-bindings/net/ti,dp83867.txt
+++ b/doc/device-tree-bindings/net/ti,dp83867.txt
@@ -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:
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 8d7c271038c..e3c403c13fc 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -123,7 +123,6 @@
#define TOUT_LOOP 1000000
#define SETUP_FRAME_LEN 192
-#define ETH_ALEN 6
struct de4x5_desc {
volatile s32 status;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index ae65b649bf9..2fe0ba6e20f 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -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 */
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index d9a897dc868..b245fbc681e 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -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;
}
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index a25b7cd9067..fe1c03e9e43 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -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;
- return phy_config(phydev);
+ free(phydev);
+ wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
+ }
+ }
+
+ return ret;
}
#endif
@@ -377,6 +399,68 @@ error:
return err;
}
+static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
+ struct dpmac_link_state *state)
+{
+ struct phy_device *phydev = NULL;
+ phy_interface_t enet_if;
+ int phy_num, phys_detected;
+ int err;
+
+ /* 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 +469,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 +489,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 +525,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 +567,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 +577,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,
@@ -553,9 +590,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);
-#endif
+ struct phy_device *phydev = NULL;
+ int phy_num;
if ((net_dev->state == ETH_STATE_PASSIVE) ||
(net_dev->state == ETH_STATE_INIT))
@@ -588,11 +624,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
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
index ee784a55ee1..3f9154b5bbc 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.h
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -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;
diff --git a/drivers/net/ldpaa_eth/ldpaa_wriop.c b/drivers/net/ldpaa_eth/ldpaa_wriop.c
index 0731a795c87..06a284ad684 100644
--- a/drivers/net/ldpaa_eth/ldpaa_wriop.c
+++ b/drivers/net/ldpaa_eth/ldpaa_wriop.c
@@ -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)
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index ab697b9bc76..8cb04b52d71 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -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 */
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 62c0c2be062..f34245ba77d 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -35,18 +35,6 @@
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)
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 0ed9bb5765c..86f689802e3 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -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
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index f941c15b270..ea7ece54b6b 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -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
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index d31c45f3b67..2286dd07e93 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -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);
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index f870e6d6620..6db6edd0d0c 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -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
@@ -48,8 +49,12 @@
#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
@@ -88,6 +93,18 @@
#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;
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index ea523435f07..590f8ce1542 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -80,10 +80,6 @@
#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. */
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index e0e3a6d570b..a78f3d233f1 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -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, \
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index b71c8f88d94..decce2fa59c 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -10,26 +10,11 @@
#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;
}
diff --git a/drivers/usb/eth/lan7x.h b/drivers/usb/eth/lan7x.h
index d1b10479359..7af610be370 100644
--- a/drivers/usb/eth/lan7x.h
+++ b/drivers/usb/eth/lan7x.h
@@ -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
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8ab9b9fe56a..90ef1f055f7 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -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++;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index d47e29e447d..eec639f8c07 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -35,12 +35,6 @@
#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).
diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h
index b8e5df615d1..85d08f69746 100644
--- a/include/dt-bindings/net/ti-dp83867.h
+++ b/include/dt-bindings/net/ti-dp83867.h
@@ -31,4 +31,19 @@
#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
diff --git a/include/fsl-mc/ldpaa_wriop.h b/include/fsl-mc/ldpaa_wriop.h
index 07e5130264b..b55c39cbb29 100644
--- a/include/fsl-mc/ldpaa_wriop.h
+++ b/include/fsl-mc/ldpaa_wriop.h
@@ -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 */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e3feb64d2d..d0f51baab40 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -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
index 00000000000..0d62aefa0dc
--- /dev/null
+++ b/include/linux/if_ether.h
@@ -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 */
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index ea20608463c..6e821d906fb 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -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.
@@ -42,7 +43,11 @@
#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)
@@ -245,9 +250,25 @@
#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 */
@@ -281,4 +302,9 @@
#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__ */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 19afb746cd0..21db032340e 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -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.
@@ -9,53 +10,55 @@
#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 */
@@ -72,19 +75,19 @@
#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 */
@@ -97,12 +100,12 @@
#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)
@@ -113,21 +116,23 @@
#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 */
@@ -139,6 +144,13 @@
#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
diff --git a/include/net.h b/include/net.h
index 2b2deb5aaef..51c099dae2e 100644
--- a/include/net.h
+++ b/include/net.h
@@ -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);
diff --git a/include/phy_interface.h b/include/phy_interface.h
index 0760d65de51..c6823189f84 100644
--- a/include/phy_interface.h
+++ b/include/phy_interface.h
@@ -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] = "",
};
diff --git a/include/usb_ether.h b/include/usb_ether.h
index 49f47d372ab..e85acadb7f5 100644
--- a/include/usb_ether.h
+++ b/include/usb_ether.h
@@ -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 */
diff --git a/net/arp.c b/net/arp.c
index b8a71684cd7..b49c3d3ced9 100644
--- 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;
+}
diff --git a/net/arp.h b/net/arp.h
index afb86958f3a..25b3c00d5c5 100644
--- 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);
diff --git a/net/net.c b/net/net.c
index 31cf306ae71..a5a216c3eee 100644
--- 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);
diff --git a/net/ping.c b/net/ping.c
index 3e5461a36a0..633c942e678 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -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;*/
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 1a7684a887b..850eabb9dc5 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -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);