Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-net
- Assorted CVE fixes - Other fixes
This commit is contained in:
commit
ece9834f7d
11
Makefile
11
Makefile
@ -1025,6 +1025,17 @@ ifneq ($(CONFIG_WDT),y)
|
||||
@echo >&2 "See doc/driver-model/MIGRATION.txt for more info."
|
||||
@echo >&2 "===================================================="
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_NET),)
|
||||
ifneq ($(CONFIG_DM_ETH),y)
|
||||
@echo >&2 "===================== WARNING ======================"
|
||||
@echo >&2 "This board does not use CONFIG_DM_ETH (Driver Model"
|
||||
@echo >&2 "for Ethernet drivers). Please update the board to use"
|
||||
@echo >&2 "CONFIG_DM_ETH before the v2020.07 release. Failure to"
|
||||
@echo >&2 "update by the deadline may result in board removal."
|
||||
@echo >&2 "See doc/driver-model/migration.rst for more info."
|
||||
@echo >&2 "===================================================="
|
||||
endif
|
||||
endif
|
||||
@# Check that this build does not use CONFIG options that we do not
|
||||
@# know about unless they are in Kconfig. All the existing CONFIG
|
||||
|
@ -245,14 +245,6 @@ config FSL_LSCH3
|
||||
config NXP_LSCH3_2
|
||||
bool
|
||||
|
||||
config FSL_MC_ENET
|
||||
bool "Management Complex network"
|
||||
depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
|
||||
default y
|
||||
select RESV_RAM
|
||||
help
|
||||
Enable Management Complex (MC) network
|
||||
|
||||
menu "Layerscape architecture"
|
||||
depends on FSL_LSCH2 || FSL_LSCH3
|
||||
|
||||
@ -593,15 +585,6 @@ config SYS_FSL_HAS_RGMII
|
||||
bool
|
||||
depends on SYS_FSL_EC1 || SYS_FSL_EC2
|
||||
|
||||
|
||||
config SYS_MC_RSV_MEM_ALIGN
|
||||
hex "Management Complex reserved memory alignment"
|
||||
depends on RESV_RAM
|
||||
default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
|
||||
help
|
||||
Reserved memory needs to be aligned for MC to use. Default value
|
||||
is 512MB.
|
||||
|
||||
config SPL_LDSCRIPT
|
||||
default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A
|
||||
|
||||
|
@ -96,6 +96,7 @@
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0x12a200 0x10>;
|
||||
device-name = "cpm-mdio";
|
||||
};
|
||||
|
||||
cpm_syscon0: system-controller@440000 {
|
||||
|
@ -96,6 +96,7 @@
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0x12a200 0x10>;
|
||||
device-name = "cps-mdio";
|
||||
};
|
||||
|
||||
cps_syscon0: system-controller@440000 {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <misc.h>
|
||||
#include <mtd.h>
|
||||
#include <mtd_node.h>
|
||||
#include <netdev.h>
|
||||
#include <phy.h>
|
||||
#include <remoteproc.h>
|
||||
#include <reset.h>
|
||||
@ -683,12 +684,21 @@ void board_quiesce_devices(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* board interface eth init */
|
||||
int board_interface_eth_init(phy_interface_t interface_type,
|
||||
bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg)
|
||||
/* eth init function : weak called in eqos driver */
|
||||
int board_interface_eth_init(struct udevice *dev,
|
||||
phy_interface_t interface_type)
|
||||
{
|
||||
u8 *syscfg;
|
||||
u32 value;
|
||||
bool eth_clk_sel_reg = false;
|
||||
bool eth_ref_clk_sel_reg = false;
|
||||
|
||||
/* Gigabit Ethernet 125MHz clock selection. */
|
||||
eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
|
||||
|
||||
/* Ethernet 50Mhz RMII clock selection */
|
||||
eth_ref_clk_sel_reg =
|
||||
dev_read_bool(dev, "st,eth_ref_clk_sel");
|
||||
|
||||
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
|
||||
|
||||
|
@ -1339,6 +1339,13 @@ config BOOTP_NTPSERVER
|
||||
bool "Request & store 'ntpserverip' from BOOTP/DHCP server"
|
||||
depends on CMD_BOOTP
|
||||
|
||||
config CMD_PCAP
|
||||
bool "pcap capture"
|
||||
help
|
||||
Selecting this will allow capturing all Ethernet packets and store
|
||||
them in physical memory in a PCAP formated file,
|
||||
later to be analyzed by PCAP reader application (IE. WireShark).
|
||||
|
||||
config BOOTP_PXE
|
||||
bool "Send PXE client arch to BOOTP/DHCP server"
|
||||
default y
|
||||
|
@ -103,6 +103,7 @@ obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
|
||||
obj-$(CONFIG_CMD_ONENAND) += onenand.o
|
||||
obj-$(CONFIG_CMD_OSD) += osd.o
|
||||
obj-$(CONFIG_CMD_PART) += part.o
|
||||
obj-$(CONFIG_CMD_PCAP) += pcap.o
|
||||
ifdef CONFIG_PCI
|
||||
obj-$(CONFIG_CMD_PCI) += pci.o
|
||||
endif
|
||||
|
@ -253,12 +253,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
case 'w':
|
||||
if (pos > 1)
|
||||
data = simple_strtoul(argv[pos--], NULL, 16);
|
||||
/* Intentional fall-through - Get reg for read and write */
|
||||
case 'r':
|
||||
if (pos > 1)
|
||||
if (extract_reg_range(argv[pos--], &devadlo, &devadhi,
|
||||
®lo, ®hi))
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
/* Intentional fall-through - Get phy for all commands */
|
||||
default:
|
||||
if (pos > 1)
|
||||
if (extract_phy_range(&argv[2], pos - 1, &bus,
|
||||
|
71
cmd/pcap.c
Normal file
71
cmd/pcap.c
Normal file
@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019
|
||||
* Ramon Fried <rfried.dev@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <net.h>
|
||||
#include <net/pcap.h>
|
||||
|
||||
static int do_pcap_init(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
phys_addr_t addr;
|
||||
unsigned int size;
|
||||
|
||||
if (argc != 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
addr = simple_strtoul(argv[1], NULL, 16);
|
||||
size = simple_strtoul(argv[2], NULL, 10);
|
||||
|
||||
return pcap_init(addr, size) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_pcap_start(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
return pcap_start_stop(true) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_pcap_stop(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
return pcap_start_stop(false) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_pcap_status(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
return pcap_print_status() ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_pcap_clear(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
return pcap_clear() ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static char pcap_help_text[] =
|
||||
"- network packet capture\n\n"
|
||||
"pcap\n"
|
||||
"pcap init\t\t\t<addr> <max_size>\n"
|
||||
"pcap start\t\t\tstart capture\n"
|
||||
"pcap stop\t\t\tstop capture\n"
|
||||
"pcap status\t\t\tprint status\n"
|
||||
"pcap clear\t\t\tclear capture buffer\n"
|
||||
"\n"
|
||||
"With:\n"
|
||||
"\t<addr>: user address to which pcap will be stored (hexedcimal)\n"
|
||||
"\t<max_size>: Maximum size of pcap file (decimal)\n"
|
||||
"\n";
|
||||
|
||||
U_BOOT_CMD_WITH_SUBCMDS(pcap, "pcap", pcap_help_text,
|
||||
U_BOOT_SUBCMD_MKENT(init, 3, 0, do_pcap_init),
|
||||
U_BOOT_SUBCMD_MKENT(start, 1, 0, do_pcap_start),
|
||||
U_BOOT_SUBCMD_MKENT(stop, 1, 0, do_pcap_stop),
|
||||
U_BOOT_SUBCMD_MKENT(status, 1, 0, do_pcap_status),
|
||||
U_BOOT_SUBCMD_MKENT(clear, 1, 0, do_pcap_clear),
|
||||
);
|
@ -49,6 +49,7 @@ CONFIG_CMD_SPI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_AXI=y
|
||||
CONFIG_CMD_AB_SELECT=y
|
||||
CONFIG_CMD_PCAP=y
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
CONFIG_CMD_TFTPSRV=y
|
||||
CONFIG_CMD_RARP=y
|
||||
|
62
doc/README.pcap
Normal file
62
doc/README.pcap
Normal file
@ -0,0 +1,62 @@
|
||||
PCAP:
|
||||
|
||||
U-boot supports live Ethernet packet capture in PCAP(2.4) format.
|
||||
This is enabled by CONFIG_CMD_PCAP.
|
||||
|
||||
The capture is stored on physical memory, and should be copied to
|
||||
a machine capable of parsing and displaying PCAP files (IE. wireshark)
|
||||
If networking works properly one can copy the capture file from physical memory
|
||||
using tftpput, or save it to local storage with (sf write, mmc write, fatwrite, etc)
|
||||
|
||||
the pcap capturing requires maximum buffer size.
|
||||
when the buffer is full an error message will be displayed and then packets
|
||||
will silently drop.
|
||||
the actual capture file size is populate in the environment variable "pcapsize".
|
||||
|
||||
Usage example:
|
||||
|
||||
# Initialize pcap capture to physical address (0x100000) with maximum size of
|
||||
# 100000 bytes.
|
||||
|
||||
# Start capture
|
||||
pcap start
|
||||
|
||||
# Initialize network activity
|
||||
env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64
|
||||
|
||||
# Stop capture
|
||||
pcap stop
|
||||
|
||||
# pcap init 0x100000 100000
|
||||
PCAP capture initialized: addr: 0xffffffff80100000 max length: 100000
|
||||
|
||||
# pcap start
|
||||
# env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64
|
||||
eth0@10000000: PHY present at 0
|
||||
eth0@10000000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
|
||||
Using eth0@10000000 device
|
||||
TFTP from server 10.0.2.2; our IP address is 10.0.2.15
|
||||
Filename 'uImage64'.
|
||||
Load address: 0xffffffff88000000
|
||||
Loading: #################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
!!! Buffer is full, consider increasing buffer size !!!
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#
|
||||
18.2 MiB/s
|
||||
done
|
||||
Bytes transferred = 8359376 (7f8dd0 hex)
|
||||
PCAP status:
|
||||
Initialized addr: 0xffffffff80100000 max length: 100000
|
||||
Status: Active. file size: 99991
|
||||
Incoming packets: 66 Outgoing packets: 67
|
||||
|
||||
# pcap stop
|
||||
# tftpput 0xffffffff80100000 $pcapsize 10.0.2.2:capture.pcap
|
||||
|
15
doc/device-tree-bindings/net/marvell-mdio.txt
Normal file
15
doc/device-tree-bindings/net/marvell-mdio.txt
Normal file
@ -0,0 +1,15 @@
|
||||
* Marvell MDIO Ethernet Controller interface
|
||||
|
||||
The Ethernet controllers of the Marvel Armada 3700 and Armada 7k/8k
|
||||
have an identical unit that provides an interface with the MDIO bus.
|
||||
This driver handles this MDIO interface.
|
||||
|
||||
Mandatory properties:
|
||||
SoC specific:
|
||||
- #address-cells: Must be <1>.
|
||||
- #size-cells: Must be <0>.
|
||||
- compatible: Should be "marvell,orion-mdio" (for SMI)
|
||||
"marvell,xmdio" (for XSMI)
|
||||
- reg: Base address and size SMI/XMSI bus.
|
||||
|
||||
Please refer to "mdio.txt" for generic MDIO bus bindings.
|
36
doc/device-tree-bindings/net/mdio.txt
Normal file
36
doc/device-tree-bindings/net/mdio.txt
Normal file
@ -0,0 +1,36 @@
|
||||
Common MDIO bus properties.
|
||||
|
||||
These are generic properties that can apply to any MDIO bus.
|
||||
|
||||
Optional properties:
|
||||
- device-name - If present it is used to name the device and MDIO bus.
|
||||
The name must be unique and must not contain spaces.
|
||||
|
||||
A list of child nodes, one per device on the bus is expected. These could be
|
||||
PHYs, switches or similar devices and child nodes should follow the specific
|
||||
binding for the device type.
|
||||
|
||||
Example :
|
||||
This example shows the structure used for the external MDIO bus on NXP LS1028A
|
||||
RDB board. Note that this MDIO device is an integrated PCI function and
|
||||
requires no compatible property for probing.
|
||||
|
||||
/* definition in SoC dtsi file */
|
||||
pcie@1f0000000 {
|
||||
|
||||
mdio0: pci@0,3 {
|
||||
#address-cells=<0>;
|
||||
#size-cells=<1>;
|
||||
reg = <0x000300 0 0 0 0>;
|
||||
status = "disabled";
|
||||
device-name = "emdio";
|
||||
};
|
||||
};
|
||||
/* definition of PHYs in RDB dts file */
|
||||
&mdio0 {
|
||||
status = "okay";
|
||||
rdb_phy0: phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
};
|
||||
|
@ -97,3 +97,11 @@ Deadline: 2019.07
|
||||
The video subsystem has supported driver model since early 2016. Maintainers
|
||||
should submit patches switching over to using CONFIG_DM_VIDEO and other base
|
||||
driver model options in time for inclusion in the 2019.07 release.
|
||||
|
||||
CONFIG_DM_ETH
|
||||
-------------
|
||||
Deadline: 2020.07
|
||||
|
||||
The network subsystem has supported the driver model since early 2015.
|
||||
Maintainers should submit patches switching over to using CONFIG_DM_ETH and
|
||||
other base driver model options in time for inclusion in the 2020.07 release.
|
||||
|
@ -1,5 +1,6 @@
|
||||
source "drivers/net/phy/Kconfig"
|
||||
source "drivers/net/pfe_eth/Kconfig"
|
||||
source "drivers/net/fsl-mc/Kconfig"
|
||||
|
||||
config DM_ETH
|
||||
bool "Enable Driver Model for Ethernet drivers"
|
||||
@ -603,4 +604,14 @@ config MDIO_MUX_I2CREG
|
||||
an I2C chip. The board it was developed for uses a mux controlled by
|
||||
on-board FPGA which in turn is accessed as a chip over I2C.
|
||||
|
||||
config MVMDIO
|
||||
bool "Marvell MDIO interface support"
|
||||
depends on DM_MDIO
|
||||
help
|
||||
This driver supports the MDIO interface found in the network
|
||||
interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
|
||||
Dove, Armada 370, Armada XP, Armada 37xx and Armada7K/8K/8KP).
|
||||
|
||||
This driver is used by the MVPP2 and MVNETA drivers.
|
||||
|
||||
endif # NETDEVICES
|
||||
|
@ -42,6 +42,7 @@ obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
|
||||
obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
|
||||
obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o
|
||||
obj-$(CONFIG_MVGBE) += mvgbe.o
|
||||
obj-$(CONFIG_MVMDIO) += mvmdio.o
|
||||
obj-$(CONFIG_MVNETA) += mvneta.o
|
||||
obj-$(CONFIG_MVPP2) += mvpp2.o
|
||||
obj-$(CONFIG_NATSEMI) += natsemi.o
|
||||
|
@ -847,7 +847,6 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
|
||||
|
||||
static const struct udevice_id designware_eth_ids[] = {
|
||||
{ .compatible = "allwinner,sun7i-a20-gmac" },
|
||||
{ .compatible = "altr,socfpga-stmmac" },
|
||||
{ .compatible = "amlogic,meson6-dwmac" },
|
||||
{ .compatible = "amlogic,meson-gx-dwmac" },
|
||||
{ .compatible = "amlogic,meson-gxbb-dwmac" },
|
||||
|
@ -621,7 +621,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void eqos_stop_clks_tegra186(struct udevice *dev)
|
||||
static void eqos_stop_clks_tegra186(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
@ -636,7 +636,7 @@ void eqos_stop_clks_tegra186(struct udevice *dev)
|
||||
debug("%s: OK\n", __func__);
|
||||
}
|
||||
|
||||
void eqos_stop_clks_stm32(struct udevice *dev)
|
||||
static void eqos_stop_clks_stm32(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
@ -1290,7 +1290,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void eqos_stop(struct udevice *dev)
|
||||
static void eqos_stop(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
int i;
|
||||
@ -1344,7 +1344,7 @@ void eqos_stop(struct udevice *dev)
|
||||
debug("%s: OK\n", __func__);
|
||||
}
|
||||
|
||||
int eqos_send(struct udevice *dev, void *packet, int length)
|
||||
static int eqos_send(struct udevice *dev, void *packet, int length)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
struct eqos_desc *tx_desc;
|
||||
@ -1385,7 +1385,7 @@ int eqos_send(struct udevice *dev, void *packet, int length)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
static int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
struct eqos_desc *rx_desc;
|
||||
@ -1409,7 +1409,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
return length;
|
||||
}
|
||||
|
||||
int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
|
||||
static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
uchar *packet_expected;
|
||||
@ -1591,8 +1591,8 @@ err_free_reset_eqos:
|
||||
}
|
||||
|
||||
/* board-specific Ethernet Interface initializations. */
|
||||
__weak int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg,
|
||||
bool eth_ref_clk_sel_reg)
|
||||
__weak int board_interface_eth_init(struct udevice *dev,
|
||||
phy_interface_t interface_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -1602,8 +1602,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
int ret;
|
||||
phy_interface_t interface;
|
||||
bool eth_clk_sel_reg = false;
|
||||
bool eth_ref_clk_sel_reg = false;
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
||||
@ -1614,15 +1612,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Gigabit Ethernet 125MHz clock selection. */
|
||||
eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
|
||||
|
||||
/* Ethernet 50Mhz RMII clock selection */
|
||||
eth_ref_clk_sel_reg =
|
||||
dev_read_bool(dev, "st,eth_ref_clk_sel");
|
||||
|
||||
ret = board_interface_eth_init(interface, eth_clk_sel_reg,
|
||||
eth_ref_clk_sel_reg);
|
||||
ret = board_interface_eth_init(dev, interface);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
|
25
drivers/net/fsl-mc/Kconfig
Normal file
25
drivers/net/fsl-mc/Kconfig
Normal file
@ -0,0 +1,25 @@
|
||||
#
|
||||
# NXP Management Complex
|
||||
#
|
||||
|
||||
menuconfig FSL_MC_ENET
|
||||
bool "NXP Management Complex"
|
||||
depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
|
||||
default y
|
||||
select RESV_RAM
|
||||
help
|
||||
Enable Management Complex (MC) network
|
||||
This is NXP Management Complex menuconfig
|
||||
that contains all MC related config options
|
||||
|
||||
if FSL_MC_ENET
|
||||
|
||||
config SYS_MC_RSV_MEM_ALIGN
|
||||
hex "Management Complex reserved memory alignment"
|
||||
depends on RESV_RAM
|
||||
default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
|
||||
help
|
||||
Reserved memory needs to be aligned for MC to use. Default value
|
||||
is 512MB.
|
||||
|
||||
endif # FSL_MC_ENET
|
@ -144,6 +144,7 @@ U_BOOT_DRIVER(enetc_mdio) = {
|
||||
|
||||
static struct pci_device_id enetc_mdio_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids);
|
||||
|
@ -296,13 +296,15 @@ static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx)
|
||||
static inline void macb_flush_rx_buffer(struct macb_device *macb)
|
||||
{
|
||||
flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
|
||||
ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN));
|
||||
ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE,
|
||||
PKTALIGN));
|
||||
}
|
||||
|
||||
static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
|
||||
{
|
||||
invalidate_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
|
||||
ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN));
|
||||
ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE,
|
||||
PKTALIGN));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CMD_NET)
|
||||
@ -643,7 +645,7 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
|
||||
|
||||
/* First check for GMAC and that it is GiB capable */
|
||||
if (gem_is_gigabit_capable(macb)) {
|
||||
lpa = macb_mdio_read(macb, MII_LPA);
|
||||
lpa = macb_mdio_read(macb, MII_STAT1000);
|
||||
|
||||
if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
|
||||
LPA_1000XHALF)) {
|
||||
|
108
drivers/net/mdio_mux_i2creg.c
Normal file
108
drivers/net/mdio_mux_i2creg.c
Normal file
@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019
|
||||
* Alex Marginean, NXP
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <miiphy.h>
|
||||
#include <i2c.h>
|
||||
|
||||
/*
|
||||
* This driver is used for MDIO muxes driven by writing to a register of an I2C
|
||||
* chip. The board it was developed for uses a mux controlled by on-board FPGA
|
||||
* which in turn is accessed as a chip over I2C.
|
||||
*/
|
||||
|
||||
struct mdio_mux_i2creg_priv {
|
||||
struct udevice *chip;
|
||||
int reg;
|
||||
int mask;
|
||||
};
|
||||
|
||||
static int mdio_mux_i2creg_select(struct udevice *mux, int cur, int sel)
|
||||
{
|
||||
struct mdio_mux_i2creg_priv *priv = dev_get_priv(mux);
|
||||
u8 val, val_old;
|
||||
|
||||
/* if last selection didn't change we're good to go */
|
||||
if (cur == sel)
|
||||
return 0;
|
||||
|
||||
val_old = dm_i2c_reg_read(priv->chip, priv->reg);
|
||||
val = (val_old & ~priv->mask) | (sel & priv->mask);
|
||||
debug("%s: chip %s, reg %x, val %x => %x\n", __func__, priv->chip->name,
|
||||
priv->reg, val_old, val);
|
||||
dm_i2c_reg_write(priv->chip, priv->reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mdio_mux_ops mdio_mux_i2creg_ops = {
|
||||
.select = mdio_mux_i2creg_select,
|
||||
};
|
||||
|
||||
static int mdio_mux_i2creg_probe(struct udevice *dev)
|
||||
{
|
||||
struct mdio_mux_i2creg_priv *priv = dev_get_priv(dev);
|
||||
ofnode chip_node, bus_node;
|
||||
struct udevice *i2c_bus;
|
||||
u32 reg_mask[2];
|
||||
u32 chip_addr;
|
||||
int err;
|
||||
|
||||
/* read the register addr/mask pair */
|
||||
err = dev_read_u32_array(dev, "mux-reg-masks", reg_mask, 2);
|
||||
if (err) {
|
||||
debug("%s: error reading mux-reg-masks property\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* parent should be an I2C chip, grandparent should be an I2C bus */
|
||||
chip_node = ofnode_get_parent(dev->node);
|
||||
bus_node = ofnode_get_parent(chip_node);
|
||||
|
||||
err = uclass_get_device_by_ofnode(UCLASS_I2C, bus_node, &i2c_bus);
|
||||
if (err) {
|
||||
debug("%s: can't find I2C bus for node %s\n", __func__,
|
||||
ofnode_get_name(bus_node));
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ofnode_read_u32(chip_node, "reg", &chip_addr);
|
||||
if (err) {
|
||||
debug("%s: can't read chip address in %s\n", __func__,
|
||||
ofnode_get_name(chip_node));
|
||||
return err;
|
||||
}
|
||||
|
||||
err = i2c_get_chip(i2c_bus, (uint)chip_addr, 1, &priv->chip);
|
||||
if (err) {
|
||||
debug("%s: can't find i2c chip device for addr %x\n", __func__,
|
||||
chip_addr);
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->reg = (int)reg_mask[0];
|
||||
priv->mask = (int)reg_mask[1];
|
||||
|
||||
debug("%s: chip %s, reg %x, mask %x\n", __func__, priv->chip->name,
|
||||
priv->reg, priv->mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id mdio_mux_i2creg_ids[] = {
|
||||
{ .compatible = "mdio-mux-i2creg" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mdio_mux_i2creg) = {
|
||||
.name = "mdio_mux_i2creg",
|
||||
.id = UCLASS_MDIO_MUX,
|
||||
.of_match = mdio_mux_i2creg_ids,
|
||||
.probe = mdio_mux_i2creg_probe,
|
||||
.ops = &mdio_mux_i2creg_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct mdio_mux_i2creg_priv),
|
||||
};
|
@ -27,7 +27,7 @@ static int mdio_sandbox_read(struct udevice *dev, int addr, int devad, int reg)
|
||||
return -ENODEV;
|
||||
if (devad != MDIO_DEVAD_NONE)
|
||||
return -ENODEV;
|
||||
if (reg < 0 || reg > SANDBOX_PHY_REG_CNT)
|
||||
if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT)
|
||||
return -ENODEV;
|
||||
|
||||
return priv->reg[reg];
|
||||
@ -45,7 +45,7 @@ static int mdio_sandbox_write(struct udevice *dev, int addr, int devad, int reg,
|
||||
return -ENODEV;
|
||||
if (devad != MDIO_DEVAD_NONE)
|
||||
return -ENODEV;
|
||||
if (reg < 0 || reg > SANDBOX_PHY_REG_CNT)
|
||||
if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT)
|
||||
return -ENODEV;
|
||||
|
||||
priv->reg[reg] = val;
|
||||
|
236
drivers/net/mvmdio.c
Normal file
236
drivers/net/mvmdio.c
Normal file
@ -0,0 +1,236 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018 Marvell International Ltd.
|
||||
* Author: Ken Ma<make@marvell.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
#include <asm/io.h>
|
||||
#include <wait_bit.h>
|
||||
|
||||
#define MVMDIO_SMI_DATA_SHIFT 0
|
||||
#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
|
||||
#define MVMDIO_SMI_PHY_REG_SHIFT 21
|
||||
#define MVMDIO_SMI_READ_OPERATION BIT(26)
|
||||
#define MVMDIO_SMI_WRITE_OPERATION 0
|
||||
#define MVMDIO_SMI_READ_VALID BIT(27)
|
||||
#define MVMDIO_SMI_BUSY BIT(28)
|
||||
|
||||
#define MVMDIO_XSMI_MGNT_REG 0x0
|
||||
#define MVMDIO_XSMI_PHYADDR_SHIFT 16
|
||||
#define MVMDIO_XSMI_DEVADDR_SHIFT 21
|
||||
#define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26)
|
||||
#define MVMDIO_XSMI_READ_OPERATION (0x7 << 26)
|
||||
#define MVMDIO_XSMI_READ_VALID BIT(29)
|
||||
#define MVMDIO_XSMI_BUSY BIT(30)
|
||||
#define MVMDIO_XSMI_ADDR_REG 0x8
|
||||
|
||||
enum mvmdio_bus_type {
|
||||
BUS_TYPE_SMI,
|
||||
BUS_TYPE_XSMI
|
||||
};
|
||||
|
||||
struct mvmdio_priv {
|
||||
void *mdio_base;
|
||||
enum mvmdio_bus_type type;
|
||||
};
|
||||
|
||||
static int mvmdio_smi_read(struct udevice *dev, int addr,
|
||||
int devad, int reg)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (devad != MDIO_DEVAD_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
|
||||
(reg << MVMDIO_SMI_PHY_REG_SHIFT) |
|
||||
MVMDIO_SMI_READ_OPERATION),
|
||||
priv->mdio_base);
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = readl(priv->mdio_base);
|
||||
if (!(val & MVMDIO_SMI_READ_VALID)) {
|
||||
pr_err("SMI bus read not valid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return val & GENMASK(15, 0);
|
||||
}
|
||||
|
||||
static int mvmdio_smi_write(struct udevice *dev, int addr, int devad,
|
||||
int reg, u16 value)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (devad != MDIO_DEVAD_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
|
||||
(reg << MVMDIO_SMI_PHY_REG_SHIFT) |
|
||||
MVMDIO_SMI_WRITE_OPERATION |
|
||||
(value << MVMDIO_SMI_DATA_SHIFT)),
|
||||
priv->mdio_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvmdio_xsmi_read(struct udevice *dev, int addr,
|
||||
int devad, int reg)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (devad == MDIO_DEVAD_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG);
|
||||
writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) |
|
||||
(devad << MVMDIO_XSMI_DEVADDR_SHIFT) |
|
||||
MVMDIO_XSMI_READ_OPERATION),
|
||||
priv->mdio_base + MVMDIO_XSMI_MGNT_REG);
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!(readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) &
|
||||
MVMDIO_XSMI_READ_VALID)) {
|
||||
pr_err("XSMI bus read not valid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0);
|
||||
}
|
||||
|
||||
static int mvmdio_xsmi_write(struct udevice *dev, int addr, int devad,
|
||||
int reg, u16 value)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (devad == MDIO_DEVAD_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
|
||||
false, CONFIG_SYS_HZ, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG);
|
||||
writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) |
|
||||
(devad << MVMDIO_XSMI_DEVADDR_SHIFT) |
|
||||
MVMDIO_XSMI_WRITE_OPERATION | value),
|
||||
priv->mdio_base + MVMDIO_XSMI_MGNT_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvmdio_read(struct udevice *dev, int addr, int devad, int reg)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
int err = -ENOTSUPP;
|
||||
|
||||
switch (priv->type) {
|
||||
case BUS_TYPE_SMI:
|
||||
err = mvmdio_smi_read(dev, addr, devad, reg);
|
||||
break;
|
||||
case BUS_TYPE_XSMI:
|
||||
err = mvmdio_xsmi_read(dev, addr, devad, reg);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mvmdio_write(struct udevice *dev, int addr, int devad, int reg,
|
||||
u16 value)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
int err = -ENOTSUPP;
|
||||
|
||||
switch (priv->type) {
|
||||
case BUS_TYPE_SMI:
|
||||
err = mvmdio_smi_write(dev, addr, devad, reg, value);
|
||||
break;
|
||||
case BUS_TYPE_XSMI:
|
||||
err = mvmdio_xsmi_write(dev, addr, devad, reg, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name the device, we use the device tree node name.
|
||||
* This can be overwritten by MDIO class code if device-name property is
|
||||
* present.
|
||||
*/
|
||||
static int mvmdio_bind(struct udevice *dev)
|
||||
{
|
||||
if (ofnode_valid(dev->node))
|
||||
device_set_name(dev, ofnode_get_name(dev->node));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get device base address and type, either C22 SMII or C45 XSMI */
|
||||
static int mvmdio_probe(struct udevice *dev)
|
||||
{
|
||||
struct mvmdio_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->mdio_base = (void *)dev_read_addr(dev);
|
||||
priv->type = (enum mvmdio_bus_type)dev_get_driver_data(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mdio_ops mvmdio_ops = {
|
||||
.read = mvmdio_read,
|
||||
.write = mvmdio_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id mvmdio_ids[] = {
|
||||
{ .compatible = "marvell,orion-mdio", .data = BUS_TYPE_SMI },
|
||||
{ .compatible = "marvell,xmdio", .data = BUS_TYPE_XSMI },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mvmdio) = {
|
||||
.name = "mvmdio",
|
||||
.id = UCLASS_MDIO,
|
||||
.of_match = mvmdio_ids,
|
||||
.bind = mvmdio_bind,
|
||||
.probe = mvmdio_probe,
|
||||
.ops = &mvmdio_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct mvmdio_priv),
|
||||
};
|
||||
|
@ -5321,6 +5321,13 @@ static void mvpp2_stop(struct udevice *dev)
|
||||
mvpp2_cleanup_txqs(port);
|
||||
}
|
||||
|
||||
static int mvpp2_write_hwaddr(struct udevice *dev)
|
||||
{
|
||||
struct mvpp2_port *port = dev_get_priv(dev);
|
||||
|
||||
return mvpp2_prs_update_mac_da(port, port->dev_addr);
|
||||
}
|
||||
|
||||
static int mvpp22_smi_phy_addr_cfg(struct mvpp2_port *port)
|
||||
{
|
||||
writel(port->phyaddr, port->priv->iface_base +
|
||||
@ -5525,6 +5532,7 @@ static const struct eth_ops mvpp2_ops = {
|
||||
.send = mvpp2_send,
|
||||
.recv = mvpp2_recv,
|
||||
.stop = mvpp2_stop,
|
||||
.write_hwaddr = mvpp2_write_hwaddr
|
||||
};
|
||||
|
||||
static struct driver mvpp2_driver = {
|
||||
|
@ -110,7 +110,6 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
|
||||
u32 phy;
|
||||
u32 reg_data;
|
||||
int timeout = MDIO_TIMEOUT;
|
||||
int val;
|
||||
|
||||
if (dev_addr == MDIO_DEVAD_NONE) {
|
||||
reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
|
||||
@ -150,7 +149,7 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
|
||||
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr,
|
||||
reg_addr, data);
|
||||
|
||||
return val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pfe_configure_serdes(struct pfe_eth_dev *priv)
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define DNS_CALLBACK
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_NET
|
||||
#ifdef CONFIG_NET
|
||||
#define NET_CALLBACKS \
|
||||
"bootfile:bootfile," \
|
||||
"ipaddr:ipaddr," \
|
||||
|
@ -36,7 +36,7 @@ enum env_flags_varaccess {
|
||||
#define CONFIG_ENV_FLAGS_LIST_STATIC ""
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_NET
|
||||
#ifdef CONFIG_NET
|
||||
#ifdef CONFIG_REGEX
|
||||
#define ETHADDR_WILDCARD "\\d*"
|
||||
#else
|
||||
|
@ -816,7 +816,7 @@ static inline int is_valid_ethaddr(const u8 *addr)
|
||||
static inline void net_random_ethaddr(uchar *addr)
|
||||
{
|
||||
int i;
|
||||
unsigned int seed = get_timer(0);
|
||||
unsigned int seed = get_ticks();
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
addr[i] = rand_r(&seed);
|
||||
|
55
include/net/pcap.h
Normal file
55
include/net/pcap.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright 2019
|
||||
* Ramon Fried <rfried.dev@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* pcap_init() - Initialize PCAP memory buffer
|
||||
*
|
||||
* @paddr physicaly memory address to store buffer
|
||||
* @size maximum size of capture file in memory
|
||||
*
|
||||
* @return 0 on success, -ERROR on error
|
||||
*/
|
||||
int pcap_init(phys_addr_t paddr, unsigned long size);
|
||||
|
||||
/**
|
||||
* pcap_start_stop() - start / stop pcap capture
|
||||
*
|
||||
* @start if true, start capture if false stop capture
|
||||
*
|
||||
* @return 0 on success, -ERROR on error
|
||||
*/
|
||||
int pcap_start_stop(bool start);
|
||||
|
||||
/**
|
||||
* pcap_clear() - clear pcap capture buffer and statistics
|
||||
*
|
||||
* @return 0 on success, -ERROR on error
|
||||
*/
|
||||
int pcap_clear(void);
|
||||
|
||||
/**
|
||||
* pcap_print_status() - print status of pcap capture
|
||||
*
|
||||
* @return 0 on success, -ERROR on error
|
||||
*/
|
||||
int pcap_print_status(void);
|
||||
|
||||
/**
|
||||
* pcap_active() - check if pcap is enabled
|
||||
*
|
||||
* @return TRUE if active, FALSE if not.
|
||||
*/
|
||||
bool pcap_active(void);
|
||||
|
||||
/**
|
||||
* pcap_post() - Post a packet to PCAP file
|
||||
*
|
||||
* @packet: packet to post
|
||||
* @len: packet length in bytes
|
||||
* @outgoing packet direction (outgoing/incoming)
|
||||
* @return 0 on success, -ERROR on error
|
||||
*/
|
||||
int pcap_post(const void *packet, size_t len, bool outgoing);
|
@ -10,6 +10,7 @@
|
||||
|
||||
#ifndef _NETDEV_H_
|
||||
#define _NETDEV_H_
|
||||
#include <phy_interface.h>
|
||||
|
||||
/*
|
||||
* Board and CPU-specific initialization functions
|
||||
@ -21,6 +22,8 @@
|
||||
*/
|
||||
|
||||
int board_eth_init(bd_t *bis);
|
||||
int board_interface_eth_init(struct udevice *dev,
|
||||
phy_interface_t interface_type);
|
||||
int cpu_eth_init(bd_t *bis);
|
||||
|
||||
/* Driver initialization prototypes */
|
||||
|
@ -22,6 +22,7 @@ obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o
|
||||
obj-$(CONFIG_NET) += net.o
|
||||
obj-$(CONFIG_CMD_NFS) += nfs.o
|
||||
obj-$(CONFIG_CMD_PING) += ping.o
|
||||
obj-$(CONFIG_CMD_PCAP) += pcap.o
|
||||
obj-$(CONFIG_CMD_RARP) += rarp.o
|
||||
obj-$(CONFIG_CMD_SNTP) += sntp.o
|
||||
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <net.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <net/pcap.h>
|
||||
#include "eth_internal.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -344,6 +345,10 @@ int eth_send(void *packet, int length)
|
||||
/* We cannot completely return the error at present */
|
||||
debug("%s: send() returned error %d\n", __func__, ret);
|
||||
}
|
||||
#if defined(CONFIG_CMD_PCAP)
|
||||
if (ret >= 0)
|
||||
pcap_post(packet, length, true);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <net.h>
|
||||
#include <phy.h>
|
||||
#include <linux/errno.h>
|
||||
#include <net/pcap.h>
|
||||
#include "eth_internal.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -352,10 +353,17 @@ int eth_is_active(struct eth_device *dev)
|
||||
|
||||
int eth_send(void *packet, int length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!eth_current)
|
||||
return -ENODEV;
|
||||
|
||||
return eth_current->send(eth_current, packet, length);
|
||||
ret = eth_current->send(eth_current, packet, length);
|
||||
#if defined(CONFIG_CMD_PCAP)
|
||||
if (ret >= 0)
|
||||
pcap_post(packet, lengeth, true);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eth_rx(void)
|
||||
|
@ -23,6 +23,17 @@ void dm_mdio_probe_devices(void)
|
||||
|
||||
static int dm_mdio_post_bind(struct udevice *dev)
|
||||
{
|
||||
const char *dt_name;
|
||||
|
||||
/* set a custom name for the MDIO device, if present in DT */
|
||||
if (ofnode_valid(dev->node)) {
|
||||
dt_name = ofnode_read_string(dev->node, "device-name");
|
||||
if (dt_name) {
|
||||
debug("renaming dev %s to %s\n", dev->name, dt_name);
|
||||
device_set_name(dev, dt_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MDIO command doesn't like spaces in names, don't allow them to keep
|
||||
* it happy
|
||||
@ -75,7 +86,7 @@ static int dm_mdio_post_probe(struct udevice *dev)
|
||||
pdata->mii_bus->write = mdio_write;
|
||||
pdata->mii_bus->reset = mdio_reset;
|
||||
pdata->mii_bus->priv = dev;
|
||||
strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN);
|
||||
strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN - 1);
|
||||
|
||||
return mdio_register(pdata->mii_bus);
|
||||
}
|
||||
|
14
net/net.c
14
net/net.c
@ -96,6 +96,9 @@
|
||||
#include <net.h>
|
||||
#include <net/fastboot.h>
|
||||
#include <net/tftp.h>
|
||||
#if defined(CONFIG_CMD_PCAP)
|
||||
#include <net/pcap.h>
|
||||
#endif
|
||||
#if defined(CONFIG_LED_STATUS)
|
||||
#include <miiphy.h>
|
||||
#include <status_led.h>
|
||||
@ -672,6 +675,11 @@ done:
|
||||
net_set_icmp_handler(NULL);
|
||||
#endif
|
||||
net_set_state(prev_net_state);
|
||||
|
||||
#if defined(CONFIG_CMD_PCAP)
|
||||
if (pcap_active())
|
||||
pcap_print_status();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1084,6 +1092,9 @@ void net_process_received_packet(uchar *in_packet, int len)
|
||||
|
||||
debug_cond(DEBUG_NET_PKT, "packet received\n");
|
||||
|
||||
#if defined(CONFIG_CMD_PCAP)
|
||||
pcap_post(in_packet, len, false);
|
||||
#endif
|
||||
net_rx_packet = in_packet;
|
||||
net_rx_packet_len = len;
|
||||
et = (struct ethernet_hdr *)in_packet;
|
||||
@ -1253,6 +1264,9 @@ void net_process_received_packet(uchar *in_packet, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ntohs(ip->udp_len) < UDP_HDR_SIZE || ntohs(ip->udp_len) > ntohs(ip->ip_len))
|
||||
return;
|
||||
|
||||
debug_cond(DEBUG_DEV_PKT,
|
||||
"received UDP (to=%pI4, from=%pI4, len=%d)\n",
|
||||
&dst_ip, &src_ip, len);
|
||||
|
19
net/nfs.c
19
net/nfs.c
@ -196,10 +196,10 @@ static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
|
||||
rpc_pkt.u.call.vers = htonl(2); /* portmapper is version 2 */
|
||||
}
|
||||
rpc_pkt.u.call.proc = htonl(rpc_proc);
|
||||
p = (uint32_t *)&(rpc_pkt.u.call.data);
|
||||
p = rpc_pkt.u.call.data;
|
||||
|
||||
if (datalen)
|
||||
memcpy((char *)p, (char *)data, datalen*sizeof(uint32_t));
|
||||
memcpy(p, data, datalen * sizeof(uint32_t));
|
||||
|
||||
pktlen = (char *)p + datalen * sizeof(uint32_t) - (char *)&rpc_pkt;
|
||||
|
||||
@ -566,11 +566,15 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
|
||||
}
|
||||
|
||||
if (supported_nfs_versions & NFSV2_FLAG) {
|
||||
if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len)
|
||||
return -NFS_RPC_DROP;
|
||||
memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
|
||||
} else { /* NFSV3_FLAG */
|
||||
filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
|
||||
if (filefh3_length > NFS3_FHSIZE)
|
||||
filefh3_length = NFS3_FHSIZE;
|
||||
if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + filefh3_length) > len)
|
||||
return -NFS_RPC_DROP;
|
||||
memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length);
|
||||
}
|
||||
|
||||
@ -579,7 +583,7 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
|
||||
|
||||
static int nfs3_get_attributes_offset(uint32_t *data)
|
||||
{
|
||||
if (ntohl(data[1]) != 0) {
|
||||
if (data[1]) {
|
||||
/* 'attributes_follow' flag is TRUE,
|
||||
* so we have attributes on 21 dwords */
|
||||
/* Skip unused values :
|
||||
@ -634,6 +638,9 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
|
||||
/* new path length */
|
||||
rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
|
||||
|
||||
if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
|
||||
return -NFS_RPC_DROP;
|
||||
|
||||
if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') {
|
||||
int pathlen;
|
||||
|
||||
@ -701,6 +708,9 @@ static int nfs_read_reply(uchar *pkt, unsigned len)
|
||||
&(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
|
||||
}
|
||||
|
||||
if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
|
||||
return -9999;
|
||||
|
||||
if (store_block(data_ptr, nfs_offset, rlen))
|
||||
return -9999;
|
||||
|
||||
@ -732,6 +742,9 @@ static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
||||
if (len > sizeof(struct rpc_t))
|
||||
return;
|
||||
|
||||
if (dest != nfs_our_port)
|
||||
return;
|
||||
|
||||
|
@ -78,7 +78,7 @@ struct rpc_t {
|
||||
NFS_MAX_ATTRS];
|
||||
} reply;
|
||||
} u;
|
||||
} __attribute__((packed));
|
||||
};
|
||||
void nfs_start(void); /* Begin NFS */
|
||||
|
||||
|
||||
|
156
net/pcap.c
Normal file
156
net/pcap.c
Normal file
@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2019 Ramon Fried <rfried.dev@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <net/pcap.h>
|
||||
#include <time.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define LINKTYPE_ETHERNET 1
|
||||
|
||||
static bool initialized;
|
||||
static bool running;
|
||||
static bool buffer_full;
|
||||
static void *buf;
|
||||
static unsigned int max_size;
|
||||
static unsigned int pos;
|
||||
|
||||
static unsigned long incoming_count;
|
||||
static unsigned long outgoing_count;
|
||||
|
||||
struct pcap_header {
|
||||
u32 magic;
|
||||
u16 version_major;
|
||||
u16 version_minor;
|
||||
s32 thiszone;
|
||||
u32 sigfigs;
|
||||
u32 snaplen;
|
||||
u32 network;
|
||||
};
|
||||
|
||||
struct pcap_packet_header {
|
||||
u32 ts_sec;
|
||||
u32 ts_usec;
|
||||
u32 incl_len;
|
||||
u32 orig_len;
|
||||
};
|
||||
|
||||
static struct pcap_header file_header = {
|
||||
.magic = 0xa1b2c3d4,
|
||||
.version_major = 2,
|
||||
.version_minor = 4,
|
||||
.snaplen = 65535,
|
||||
.network = LINKTYPE_ETHERNET,
|
||||
};
|
||||
|
||||
int pcap_init(phys_addr_t paddr, unsigned long size)
|
||||
{
|
||||
buf = map_physmem(paddr, size, 0);
|
||||
if (!buf) {
|
||||
printf("Failed mapping PCAP memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
printf("PCAP capture initialized: addr: 0x%lx max length: %lu\n",
|
||||
(unsigned long)buf, size);
|
||||
|
||||
memcpy(buf, &file_header, sizeof(file_header));
|
||||
pos = sizeof(file_header);
|
||||
max_size = size;
|
||||
initialized = true;
|
||||
running = false;
|
||||
buffer_full = false;
|
||||
incoming_count = 0;
|
||||
outgoing_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcap_start_stop(bool start)
|
||||
{
|
||||
if (!initialized) {
|
||||
printf("error: pcap was not initialized\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
running = start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcap_clear(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
printf("error: pcap was not initialized\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pos = sizeof(file_header);
|
||||
incoming_count = 0;
|
||||
outgoing_count = 0;
|
||||
buffer_full = false;
|
||||
|
||||
printf("pcap capture cleared\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcap_post(const void *packet, size_t len, bool outgoing)
|
||||
{
|
||||
struct pcap_packet_header header;
|
||||
u64 cur_time = timer_get_us();
|
||||
|
||||
if (!initialized || !running || !buf)
|
||||
return -ENODEV;
|
||||
|
||||
if (buffer_full)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((pos + len + sizeof(header)) >= max_size) {
|
||||
buffer_full = true;
|
||||
printf("\n!!! Buffer is full, consider increasing buffer size !!!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
header.ts_sec = cur_time / 1000000;
|
||||
header.ts_usec = cur_time % 1000000;
|
||||
header.incl_len = len;
|
||||
header.orig_len = len;
|
||||
|
||||
memcpy(buf + pos, &header, sizeof(header));
|
||||
pos += sizeof(header);
|
||||
memcpy(buf + pos, packet, len);
|
||||
pos += len;
|
||||
|
||||
if (outgoing)
|
||||
outgoing_count++;
|
||||
else
|
||||
incoming_count++;
|
||||
|
||||
env_set_hex("pcapsize", pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcap_print_status(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
printf("pcap was not initialized\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
printf("PCAP status:\n");
|
||||
printf("\tInitialized addr: 0x%lx\tmax length: %u\n",
|
||||
(unsigned long)buf, max_size);
|
||||
printf("\tStatus: %s.\t file size: %u\n", running ? "Active" : "Idle",
|
||||
pos);
|
||||
printf("\tIncoming packets: %lu Outgoing packets: %lu\n",
|
||||
incoming_count, outgoing_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool pcap_active(void)
|
||||
{
|
||||
return running;
|
||||
}
|
Loading…
Reference in New Issue
Block a user