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

lime2-spi
Tom Rini 6 years ago
commit 0223462b37
  1. 93
      arch/sandbox/include/asm/eth.h
  2. 1
      board/Synology/ds414/cmd_syno.c
  3. 18
      board/freescale/ls1088a/eth_ls1088aqds.c
  4. 21
      board/freescale/ls1088a/eth_ls1088ardb.c
  5. 26
      board/freescale/ls2080aqds/eth.c
  6. 24
      board/freescale/ls2080ardb/eth_ls2080rdb.c
  7. 8
      doc/device-tree-bindings/net/ti,dp83867.txt
  8. 1
      drivers/net/dc2114x.c
  9. 2
      drivers/net/eepro100.c
  10. 6
      drivers/net/fsl-mc/mc.c
  11. 171
      drivers/net/ldpaa_eth/ldpaa_eth.c
  12. 1
      drivers/net/ldpaa_eth/ldpaa_eth.h
  13. 69
      drivers/net/ldpaa_eth/ldpaa_wriop.c
  14. 8
      drivers/net/mvneta.c
  15. 13
      drivers/net/mvpp2.c
  16. 1
      drivers/net/natsemi.c
  17. 1
      drivers/net/ns8382x.c
  18. 4
      drivers/net/pch_gbe.c
  19. 93
      drivers/net/phy/ti.c
  20. 4
      drivers/net/rtl8139.c
  21. 4
      drivers/net/rtl8169.c
  22. 417
      drivers/net/sandbox.c
  23. 2
      drivers/usb/eth/lan7x.h
  24. 9
      drivers/usb/gadget/ether.c
  25. 6
      drivers/usb/gadget/rndis.c
  26. 15
      include/dt-bindings/net/ti-dp83867.h
  27. 46
      include/fsl-mc/ldpaa_wriop.h
  28. 19
      include/linux/compat.h
  29. 178
      include/linux/if_ether.h
  30. 34
      include/linux/mdio.h
  31. 126
      include/linux/mii.h
  32. 16
      include/net.h
  33. 8
      include/phy_interface.h
  34. 10
      include/usb_ether.h
  35. 20
      net/arp.c
  36. 1
      net/arp.h
  37. 43
      net/net.c
  38. 14
      net/ping.c
  39. 170
      test/dm/eth.c

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

@ -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="

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

@ -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:

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

@ -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:

@ -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:

@ -123,7 +123,6 @@
#define TOUT_LOOP 1000000
#define SETUP_FRAME_LEN 192
#define ETH_ALEN 6
struct de4x5_desc {
volatile s32 status;

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

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

@ -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

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

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

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

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

@ -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

@ -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

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

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

@ -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. */

@ -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, \

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

@ -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

@ -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++;

@ -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).

@ -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

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

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

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

@ -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__ */

@ -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

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

@ -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] = "",
};

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

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

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

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

@ -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;*/

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

Loading…
Cancel
Save