mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-net
This commit is contained in:
commit
0223462b37
39 changed files with 1294 additions and 409 deletions
|
@ -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 = address;
|
||||
dpmac_info[i].phy_addr[phy_num] = 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,13 +47,288 @@ void sandbox_eth_skip_timeout(void)
|
|||
skip_timeout = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
if (ntohs(eth->et_protlen) != PROT_ARP)
|
||||
return -EAGAIN;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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_packet_buffer = net_rx_packets[0];
|
||||
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;
|
||||
}
|
||||
|
@ -67,87 +336,13 @@ static int sb_eth_start(struct udevice *dev)
|
|||
static int sb_eth_send(struct udevice *dev, void *packet, int length)
|
||||
{
|
||||
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
||||
struct ethernet_hdr *eth = packet;
|
||||
|
||||
debug("eth_sandbox: Send packet %d\n", length);
|
||||
|
||||
if (dev->seq >= 0 && dev->seq < ARRAY_SIZE(disabled) &&
|
||||
disabled[dev->seq])
|
||||
if (priv->disabled)
|
||||
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;
|
||||
return priv->tx_handler(dev, packet, length);
|
||||
}
|
||||
|
||||
static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
|
@ -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 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_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_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)
|
||||
|
|
178
include/linux/if_ether.h
Normal file
178
include/linux/if_ether.h
Normal file
|
@ -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 */
|
||||
|
|
20
net/arp.c
20
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
43
net/net.c
43
net/net.c
|
@ -799,8 +799,24 @@ 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;
|
||||
|
@ -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);
|
||||
|
|
14
net/ping.c
14
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;*/
|
||||
|
|
170
test/dm/eth.c
170
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);
|
||||
|
|
Loading…
Reference in a new issue