Port some parts of the stmmac selftest to the FEC. This patch was tested
on iMX6DL.
With this tests it is possible to detect some basic issues like:
- MAC loopback fail: most probably wrong clock configuration.
- PHY loopback fail: incorrect RGMII timings, damaged traces, etc
Signed-off-by: Oleksij Rempel
---
drivers/net/ethernet/freescale/Makefile | 2 +-
drivers/net/ethernet/freescale/fec.h | 6 +
drivers/net/ethernet/freescale/fec_main.c | 6 +
.../net/ethernet/freescale/fec_selftests.c| 425 ++
4 files changed, 438 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/freescale/fec_selftests.c
diff --git a/drivers/net/ethernet/freescale/Makefile
b/drivers/net/ethernet/freescale/Makefile
index 67c436400352..b936c6fe5911 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_FEC) += fec.o
-fec-objs :=fec_main.o fec_ptp.o
+fec-objs :=fec_main.o fec_ptp.o fec_selftests.o
obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
diff --git a/drivers/net/ethernet/freescale/fec.h
b/drivers/net/ethernet/freescale/fec.h
index 0602d5d5d2ee..ade6a80934bf 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -467,6 +467,9 @@ struct bufdesc_ex {
*/
#define FEC_QUIRK_NO_HARD_RESET(1 << 18)
+#define FEC_ENET_DRT (1 << 1)
+#define FEC_ENET_LOOP (1 << 0)
+
struct bufdesc_prop {
int qid;
/* Address of Rx and Tx buffers */
@@ -604,6 +607,9 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev);
void fec_ptp_disable_hwts(struct net_device *ndev);
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
+void fec_selftest(struct net_device *ndev, struct ethtool_test *etest, u64
*data);
+int fec_selftest_get_count(void);
+void fec_selftest_get_strings(u8 *data);
//
#endif /* FEC_H */
diff --git a/drivers/net/ethernet/freescale/fec_main.c
b/drivers/net/ethernet/freescale/fec_main.c
index 3db882322b2b..2ca72f7b5b7d 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2474,6 +2474,9 @@ static void fec_enet_get_strings(struct net_device
*netdev,
{
int i;
switch (stringset) {
+ case ETH_SS_TEST:
+ fec_selftest_get_strings(data);
+ break;
case ETH_SS_STATS:
for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
memcpy(data + i * ETH_GSTRING_LEN,
@@ -2485,6 +2488,8 @@ static void fec_enet_get_strings(struct net_device
*netdev,
static int fec_enet_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
+ case ETH_SS_TEST:
+ return fec_selftest_get_count();
case ETH_SS_STATS:
return ARRAY_SIZE(fec_stats);
default:
@@ -2738,6 +2743,7 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
.set_wol= fec_enet_set_wol,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .self_test = fec_selftest,
};
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/ethernet/freescale/fec_selftests.c
b/drivers/net/ethernet/freescale/fec_selftests.c
new file mode 100644
index ..788213a6454f
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fec_selftests.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Synopsys, Inc. and/or its affiliates.
+ * stmmac Selftests Support
+ *
+ * Author: Jose Abreu
+ *
+ * Ported from stmmac to the FEC by:
+ * Copyright (C) 2021 Oleksij Rempel
+ */
+
+#include
+#include
+#include
+
+#include "fec.h"
+
+struct fec_packet_attrs {
+ unsigned char *src;
+ unsigned char *dst;
+ u32 ip_src;
+ u32 ip_dst;
+ int tcp;
+ int sport;
+ int dport;
+ int timeout;
+ int size;
+ int max_size;
+ u8 id;
+ u16 queue_mapping;
+};
+
+struct fec_test_priv {
+ struct fec_packet_attrs *packet;
+ struct packet_type pt;
+ struct completion comp;
+ int double_vlan;
+ int vlan_id;
+ int ok;
+};
+
+struct fechdr {
+ __be32 version;
+ __be64 magic;
+ u8 id;
+} __packed;
+
+static u8 fec_test_next_id;
+
+#define FEC_TEST_PKT_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) + \
+ sizeof(struct fechdr))
+#define FEC_TEST_PKT_MAGIC 0xdeadcafecafedeadULL
+#define FEC_LB_TIMEOUT msecs_to_jiffies(200)
+
+static struct sk_buff *fec_test_get_udp_skb(struct fec_enet_private *fep,
+ struct fec_packet_attrs *attr)
+{