* [PATCH net-next v1 0/3] provide basic selftest support for the ethernet FEC driver @ 2021-03-30 13:54 Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Oleksij Rempel @ 2021-03-30 13:54 UTC (permalink / raw) To: Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Oleksij Rempel, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker This patch set provides diagnostic capabilities for some iMX based boards. So far I add only initial infrastructure with basic tests and fixed some PHY drivers. To validate this tests, I made some common missconfigurations like wrong RGMII type, not configured clock providers and so on. Oleksij Rempel (3): net: phy: micrel: KSZ8081: add loopback support net: phy: at803x: AR8085: add loopback support net: fec: add basic selftest support 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 ++++++++++++++++++ drivers/net/phy/at803x.c | 25 ++ drivers/net/phy/micrel.c | 1 + 6 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/freescale/fec_selftests.c -- 2.29.2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support 2021-03-30 13:54 [PATCH net-next v1 0/3] provide basic selftest support for the ethernet FEC driver Oleksij Rempel @ 2021-03-30 13:54 ` Oleksij Rempel 2021-03-30 14:06 ` Marc Kleine-Budde 2021-03-30 14:39 ` Andrew Lunn 2021-03-30 13:54 ` [PATCH net-next v1 2/3] net: phy: at803x: AR8085: " Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 3/3] net: fec: add basic selftest support Oleksij Rempel 2 siblings, 2 replies; 12+ messages in thread From: Oleksij Rempel @ 2021-03-30 13:54 UTC (permalink / raw) To: Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Oleksij Rempel, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker PHY loopback is needed for the ethernet controller self test support. This PHY was tested with the FEC sefltest. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- drivers/net/phy/micrel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index a14a00328fa3..f05345f1c602 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -1311,6 +1311,7 @@ static struct phy_driver ksphy_driver[] = { .get_stats = kszphy_get_stats, .suspend = kszphy_suspend, .resume = kszphy_resume, + .set_loopback = genphy_loopback, }, { .phy_id = PHY_ID_KSZ8061, .name = "Micrel KSZ8061", -- 2.29.2 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel @ 2021-03-30 14:06 ` Marc Kleine-Budde 2021-03-30 14:39 ` Andrew Lunn 1 sibling, 0 replies; 12+ messages in thread From: Marc Kleine-Budde @ 2021-03-30 14:06 UTC (permalink / raw) To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Philippe Schenker, netdev, linux-kernel, Russell King, linux-imx, kernel, David Jander, Fabio Estevam, linux-arm-kernel [-- Attachment #1.1: Type: text/plain, Size: 531 bytes --] On 3/30/21 3:54 PM, Oleksij Rempel wrote: > PHY loopback is needed for the ethernet controller self test support. > This PHY was tested with the FEC sefltest. selftest Same typo is in the other patches, too. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel 2021-03-30 14:06 ` Marc Kleine-Budde @ 2021-03-30 14:39 ` Andrew Lunn 1 sibling, 0 replies; 12+ messages in thread From: Andrew Lunn @ 2021-03-30 14:39 UTC (permalink / raw) To: Oleksij Rempel Cc: Shawn Guo, Sascha Hauer, Florian Fainelli, Heiner Kallweit, Fugang Duan, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker On Tue, Mar 30, 2021 at 03:54:05PM +0200, Oleksij Rempel wrote: > PHY loopback is needed for the ethernet controller self test support. > This PHY was tested with the FEC sefltest. > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Apart from the typo Reviewed-by: Andrew Lunn <andrew@lunn.ch> Andrew ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v1 2/3] net: phy: at803x: AR8085: add loopback support 2021-03-30 13:54 [PATCH net-next v1 0/3] provide basic selftest support for the ethernet FEC driver Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel @ 2021-03-30 13:54 ` Oleksij Rempel 2021-03-30 14:08 ` Marc Kleine-Budde 2021-03-30 14:49 ` Andrew Lunn 2021-03-30 13:54 ` [PATCH net-next v1 3/3] net: fec: add basic selftest support Oleksij Rempel 2 siblings, 2 replies; 12+ messages in thread From: Oleksij Rempel @ 2021-03-30 13:54 UTC (permalink / raw) To: Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Oleksij Rempel, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker PHY loopback is needed for the ethernet controller self test support. This PHY was tested with the FEC sefltest. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index d7799beb811c..8679738cf2ab 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -326,6 +326,30 @@ static int at803x_resume(struct phy_device *phydev) return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); } +static int at803x_loopback(struct phy_device *phydev, bool enable) +{ + int ret; + + if (enable) + ret = phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE); + else + ret = phy_set_bits(phydev, MII_BMCR, BMCR_ANENABLE); + + if (ret) + return ret; + + ret = genphy_loopback(phydev, enable); + + /* + * Loop back needs some time to start transmitting packets in the loop. + * Documentation says nothing about it, so I take time which seems to + * work on AR8085. + */ + msleep(1); + + return ret; +} + static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { @@ -1128,6 +1152,7 @@ static struct phy_driver at803x_driver[] = { .get_wol = at803x_get_wol, .suspend = at803x_suspend, .resume = at803x_resume, + .set_loopback = at803x_loopback, /* PHY_GBIT_FEATURES */ .read_status = at803x_read_status, .config_intr = at803x_config_intr, -- 2.29.2 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 2/3] net: phy: at803x: AR8085: add loopback support 2021-03-30 13:54 ` [PATCH net-next v1 2/3] net: phy: at803x: AR8085: " Oleksij Rempel @ 2021-03-30 14:08 ` Marc Kleine-Budde 2021-03-30 14:49 ` Andrew Lunn 1 sibling, 0 replies; 12+ messages in thread From: Marc Kleine-Budde @ 2021-03-30 14:08 UTC (permalink / raw) To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Philippe Schenker, netdev, linux-kernel, Russell King, linux-imx, kernel, David Jander, Fabio Estevam, linux-arm-kernel [-- Attachment #1.1: Type: text/plain, Size: 1541 bytes --] On 3/30/21 3:54 PM, Oleksij Rempel wrote: > PHY loopback is needed for the ethernet controller self test support. > This PHY was tested with the FEC sefltest. > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> > --- > drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c > index d7799beb811c..8679738cf2ab 100644 > --- a/drivers/net/phy/at803x.c > +++ b/drivers/net/phy/at803x.c > @@ -326,6 +326,30 @@ static int at803x_resume(struct phy_device *phydev) > return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); > } > > +static int at803x_loopback(struct phy_device *phydev, bool enable) > +{ > + int ret; > + > + if (enable) > + ret = phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE); > + else > + ret = phy_set_bits(phydev, MII_BMCR, BMCR_ANENABLE); > + > + if (ret) > + return ret; > + > + ret = genphy_loopback(phydev, enable); > + > + /* > + * Loop back needs some time to start transmitting packets in the loop. > + * Documentation says nothing about it, so I take time which seems to > + * work on AR8085. > + */ /* Keep in mind the net multi line comment * style. */ Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 2/3] net: phy: at803x: AR8085: add loopback support 2021-03-30 13:54 ` [PATCH net-next v1 2/3] net: phy: at803x: AR8085: " Oleksij Rempel 2021-03-30 14:08 ` Marc Kleine-Budde @ 2021-03-30 14:49 ` Andrew Lunn 1 sibling, 0 replies; 12+ messages in thread From: Andrew Lunn @ 2021-03-30 14:49 UTC (permalink / raw) To: Oleksij Rempel Cc: Shawn Guo, Sascha Hauer, Florian Fainelli, Heiner Kallweit, Fugang Duan, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker On Tue, Mar 30, 2021 at 03:54:06PM +0200, Oleksij Rempel wrote: > PHY loopback is needed for the ethernet controller self test support. > This PHY was tested with the FEC sefltest. > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> > --- > drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c > index d7799beb811c..8679738cf2ab 100644 > --- a/drivers/net/phy/at803x.c > +++ b/drivers/net/phy/at803x.c > @@ -326,6 +326,30 @@ static int at803x_resume(struct phy_device *phydev) > return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); > } > > +static int at803x_loopback(struct phy_device *phydev, bool enable) > +{ > + int ret; > + > + if (enable) > + ret = phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE); > + else > + ret = phy_set_bits(phydev, MII_BMCR, BMCR_ANENABLE); Auto-neg might of been turned off when entering self test. So you should leave it off when existing self test. Or maybe call phy_config_aneg() which should reconfigure the PHY back how it was. Andrew ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v1 3/3] net: fec: add basic selftest support 2021-03-30 13:54 [PATCH net-next v1 0/3] provide basic selftest support for the ethernet FEC driver Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 2/3] net: phy: at803x: AR8085: " Oleksij Rempel @ 2021-03-30 13:54 ` Oleksij Rempel 2021-03-31 1:07 ` kernel test robot 2021-03-31 12:27 ` Andrew Lunn 2 siblings, 2 replies; 12+ messages in thread From: Oleksij Rempel @ 2021-03-30 13:54 UTC (permalink / raw) To: Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: Oleksij Rempel, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker 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 <o.rempel@pengutronix.de> --- 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 000000000000..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 <joabreu@synopsys.com> + * + * Ported from stmmac to the FEC by: + * Copyright (C) 2021 Oleksij Rempel <o.rempel@pengutronix.de> + */ + +#include <linux/phy.h> +#include <net/tcp.h> +#include <net/udp.h> + +#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) +{ + struct sk_buff *skb = NULL; + struct udphdr *uhdr = NULL; + struct tcphdr *thdr = NULL; + struct fechdr *shdr; + struct ethhdr *ehdr; + struct iphdr *ihdr; + int iplen, size; + + size = attr->size + FEC_TEST_PKT_SIZE; + + if (attr->tcp) + size += sizeof(struct tcphdr); + else + size += sizeof(struct udphdr); + + if (attr->max_size && (attr->max_size > size)) + size = attr->max_size; + + skb = netdev_alloc_skb(fep->netdev, size); + if (!skb) + return NULL; + + prefetchw(skb->data); + + ehdr = skb_push(skb, ETH_HLEN); + skb_reset_mac_header(skb); + + skb_set_network_header(skb, skb->len); + ihdr = skb_put(skb, sizeof(*ihdr)); + + skb_set_transport_header(skb, skb->len); + if (attr->tcp) + thdr = skb_put(skb, sizeof(*thdr)); + else + uhdr = skb_put(skb, sizeof(*uhdr)); + eth_zero_addr(ehdr->h_dest); + if (attr->src) + ether_addr_copy(ehdr->h_source, attr->src); + if (attr->dst) + ether_addr_copy(ehdr->h_dest, attr->dst); + + ehdr->h_proto = htons(ETH_P_IP); + + if (attr->tcp) { + thdr->source = htons(attr->sport); + thdr->dest = htons(attr->dport); + thdr->doff = sizeof(struct tcphdr) / 4; + thdr->check = 0; + } else { + uhdr->source = htons(attr->sport); + uhdr->dest = htons(attr->dport); + uhdr->len = htons(sizeof(*shdr) + sizeof(*uhdr) + attr->size); + if (attr->max_size) + uhdr->len = htons(attr->max_size - + (sizeof(*ihdr) + sizeof(*ehdr))); + uhdr->check = 0; + } + + ihdr->ihl = 5; + ihdr->ttl = 32; + ihdr->version = 4; + if (attr->tcp) + ihdr->protocol = IPPROTO_TCP; + else + ihdr->protocol = IPPROTO_UDP; + iplen = sizeof(*ihdr) + sizeof(*shdr) + attr->size; + if (attr->tcp) + iplen += sizeof(*thdr); + else + iplen += sizeof(*uhdr); + + if (attr->max_size) + iplen = attr->max_size - sizeof(*ehdr); + + ihdr->tot_len = htons(iplen); + ihdr->frag_off = 0; + ihdr->saddr = htonl(attr->ip_src); + ihdr->daddr = htonl(attr->ip_dst); + ihdr->tos = 0; + ihdr->id = 0; + ip_send_check(ihdr); + + shdr = skb_put(skb, sizeof(*shdr)); + shdr->version = 0; + shdr->magic = cpu_to_be64(FEC_TEST_PKT_MAGIC); + attr->id = fec_test_next_id; + shdr->id = fec_test_next_id++; + + if (attr->size) + skb_put(skb, attr->size); + if (attr->max_size && (attr->max_size > skb->len)) + skb_put(skb, attr->max_size - skb->len); + + skb->csum = 0; + skb->ip_summed = CHECKSUM_PARTIAL; + if (attr->tcp) { + thdr->check = ~tcp_v4_check(skb->len, ihdr->saddr, ihdr->daddr, 0); + skb->csum_start = skb_transport_header(skb) - skb->head; + skb->csum_offset = offsetof(struct tcphdr, check); + } else { + udp4_hwcsum(skb, ihdr->saddr, ihdr->daddr); + } + + skb->protocol = htons(ETH_P_IP); + skb->pkt_type = PACKET_HOST; + skb->dev = fep->netdev; + + return skb; +} + +static int fec_test_loopback_validate(struct sk_buff *skb, + struct net_device *ndev, + struct packet_type *pt, + struct net_device *orig_ndev) +{ + struct fec_test_priv *tpriv = pt->af_packet_priv; + unsigned char *src = tpriv->packet->src; + unsigned char *dst = tpriv->packet->dst; + struct fechdr *shdr; + struct ethhdr *ehdr; + struct udphdr *uhdr; + struct tcphdr *thdr; + struct iphdr *ihdr; + + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) + goto out; + + if (skb_linearize(skb)) + goto out; + if (skb_headlen(skb) < (FEC_TEST_PKT_SIZE - ETH_HLEN)) + goto out; + + ehdr = (struct ethhdr *)skb_mac_header(skb); + if (dst) { + if (!ether_addr_equal_unaligned(ehdr->h_dest, dst)) + goto out; + } + + if (src) { + if (!ether_addr_equal_unaligned(ehdr->h_source, src)) + goto out; + } + + ihdr = ip_hdr(skb); + if (tpriv->double_vlan) + ihdr = (struct iphdr *)(skb_network_header(skb) + 4); + + if (tpriv->packet->tcp) { + if (ihdr->protocol != IPPROTO_TCP) + goto out; + + thdr = (struct tcphdr *)((u8 *)ihdr + 4 * ihdr->ihl); + if (thdr->dest != htons(tpriv->packet->dport)) + goto out; + + shdr = (struct fechdr *)((u8 *)thdr + sizeof(*thdr)); + } else { + if (ihdr->protocol != IPPROTO_UDP) + goto out; + + uhdr = (struct udphdr *)((u8 *)ihdr + 4 * ihdr->ihl); + if (uhdr->dest != htons(tpriv->packet->dport)) + goto out; + + shdr = (struct fechdr *)((u8 *)uhdr + sizeof(*uhdr)); + } + + if (shdr->magic != cpu_to_be64(FEC_TEST_PKT_MAGIC)) + goto out; + if (tpriv->packet->id != shdr->id) + goto out; + + tpriv->ok = true; + complete(&tpriv->comp); +out: + kfree_skb(skb); + return 0; +} + +static int __fec_test_loopback(struct fec_enet_private *fep, + struct fec_packet_attrs *attr) +{ + struct fec_test_priv *tpriv; + struct sk_buff *skb = NULL; + int ret = 0; + + tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + if (!tpriv) + return -ENOMEM; + + tpriv->ok = false; + init_completion(&tpriv->comp); + + tpriv->pt.type = htons(ETH_P_IP); + tpriv->pt.func = fec_test_loopback_validate; + tpriv->pt.dev = fep->netdev; + tpriv->pt.af_packet_priv = tpriv; + tpriv->packet = attr; + + skb = fec_test_get_udp_skb(fep, attr); + if (!skb) { + ret = -ENOMEM; + goto cleanup; + } + + ret = dev_direct_xmit(skb, attr->queue_mapping); + if (ret) + goto cleanup; + + if (!attr->timeout) + attr->timeout = FEC_LB_TIMEOUT; + + wait_for_completion_timeout(&tpriv->comp, attr->timeout); + ret = tpriv->ok ? 0 : -ETIMEDOUT; + +cleanup: + kfree(tpriv); + return ret; +} + +static int fec_test_mac_loopback(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct fec_packet_attrs attr = { }; + + attr.dst = ndev->dev_addr; + return __fec_test_loopback(fep, &attr); +} + +static int fec_test_phy_loopback(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct fec_packet_attrs attr = { }; + + attr.dst = ndev->dev_addr; + return __fec_test_loopback(fep, &attr); +} + +static int fec_test_tcp(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct fec_packet_attrs attr = { }; + + attr.dst = ndev->dev_addr; + attr.tcp = true; + return __fec_test_loopback(fep, &attr); +} + +#define FEC_LOOPBACK_MAC 0 +#define FEC_LOOPBACK_PHY 1 + +static const struct fec_test { + char name[ETH_GSTRING_LEN]; + int lb; + int (*fn)(struct net_device *ndev); +} fec_selftests[] = { + { + .name = "MAC Loopback, UDP ", + .lb = FEC_LOOPBACK_MAC, + .fn = fec_test_mac_loopback, + }, { + .name = "PHY Loopback, UDP ", + .lb = FEC_LOOPBACK_PHY, + .fn = fec_test_phy_loopback, + }, { + .name = "PHY Loopback, TCP ", + .lb = FEC_LOOPBACK_PHY, + .fn = fec_test_tcp, + }, +}; + +void fec_selftest(struct net_device *ndev, + struct ethtool_test *etest, u64 *buf) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + int count = fec_selftest_get_count(); + u32 tmp, r_cntrl; + int i, ret; + + memset(buf, 0, sizeof(*buf) * count); + fec_test_next_id = 0; + + if (etest->flags != ETH_TEST_FL_OFFLINE) { + netdev_err(ndev, "Only offline tests are supported\n"); + etest->flags |= ETH_TEST_FL_FAILED; + return; + } else if (!netif_carrier_ok(ndev)) { + netdev_err(ndev, "You need valid Link to execute tests\n"); + etest->flags |= ETH_TEST_FL_FAILED; + return; + } + + /* Wait for queues drain */ + msleep(200); + for (i = 0; i < count; i++) { + ret = 0; + + + switch (fec_selftests[i].lb) { + case FEC_LOOPBACK_PHY: + ret = -EOPNOTSUPP; + if (ndev->phydev) + ret = phy_loopback(ndev->phydev, true); + if (!ret) + break; + fallthrough; + case FEC_LOOPBACK_MAC: + /* disable half duplex if present and enable MAC loop back */ + r_cntrl = readl(fep->hwp + FEC_R_CNTRL); + tmp = FEC_ENET_LOOP | (r_cntrl & ~FEC_ENET_DRT); + writel(tmp, fep->hwp + FEC_R_CNTRL); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + /* + * First tests will always be MAC / PHY loobpack. If any of + * them is not supported we abort earlier. + */ + if (ret) { + netdev_err(ndev, "Loopback is not supported\n"); + etest->flags |= ETH_TEST_FL_FAILED; + break; + } + + ret = fec_selftests[i].fn(ndev); + if (ret && (ret != -EOPNOTSUPP)) + etest->flags |= ETH_TEST_FL_FAILED; + buf[i] = ret; + + switch (fec_selftests[i].lb) { + case FEC_LOOPBACK_PHY: + ret = -EOPNOTSUPP; + if (ndev->phydev) + ret = phy_loopback(ndev->phydev, false); + if (!ret) + break; + fallthrough; + case FEC_LOOPBACK_MAC: + writel(r_cntrl, fep->hwp + FEC_R_CNTRL); + break; + default: + break; + } + } +} + +int fec_selftest_get_count(void) +{ + return ARRAY_SIZE(fec_selftests); +} + +void fec_selftest_get_strings(u8 *data) +{ + u8 *p = data; + int i; + + for (i = 0; i < fec_selftest_get_count(); i++) { + snprintf(p, ETH_GSTRING_LEN, "%2d. %s", i + 1, + fec_selftests[i].name); + p += ETH_GSTRING_LEN; + } +} + + -- 2.29.2 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 3/3] net: fec: add basic selftest support 2021-03-30 13:54 ` [PATCH net-next v1 3/3] net: fec: add basic selftest support Oleksij Rempel @ 2021-03-31 1:07 ` kernel test robot 2021-03-31 12:27 ` Andrew Lunn 1 sibling, 0 replies; 12+ messages in thread From: kernel test robot @ 2021-03-31 1:07 UTC (permalink / raw) To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Andrew Lunn, Florian Fainelli, Heiner Kallweit, Fugang Duan Cc: kbuild-all, clang-built-linux, Oleksij Rempel, kernel, netdev, linux-arm-kernel [-- Attachment #1: Type: text/plain, Size: 1940 bytes --] Hi Oleksij, I love your patch! Yet something to improve: [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/Oleksij-Rempel/provide-basic-selftest-support-for-the-ethernet-FEC-driver/20210330-215711 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git d0922bf7981799fd86e248de330fb4152399d6c2 config: arm64-randconfig-r012-20210330 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 482283042f795ecc27838a3b2f76b5494991401c) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/80875535f65f814de8c63762039c8842a653d1e4 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Oleksij-Rempel/provide-basic-selftest-support-for-the-ethernet-FEC-driver/20210330-215711 git checkout 80875535f65f814de8c63762039c8842a653d1e4 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> ld.lld: error: undefined symbol: ip_send_check >>> referenced by fec_selftests.c >>> net/ethernet/freescale/fec_selftests.o:(__fec_test_loopback) in archive drivers/built-in.a -- >> ld.lld: error: undefined symbol: udp4_hwcsum >>> referenced by fec_selftests.c >>> net/ethernet/freescale/fec_selftests.o:(__fec_test_loopback) in archive drivers/built-in.a --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 33516 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 3/3] net: fec: add basic selftest support 2021-03-30 13:54 ` [PATCH net-next v1 3/3] net: fec: add basic selftest support Oleksij Rempel 2021-03-31 1:07 ` kernel test robot @ 2021-03-31 12:27 ` Andrew Lunn 2021-04-01 7:47 ` Oleksij Rempel 1 sibling, 1 reply; 12+ messages in thread From: Andrew Lunn @ 2021-03-31 12:27 UTC (permalink / raw) To: Oleksij Rempel Cc: Shawn Guo, Sascha Hauer, Florian Fainelli, Heiner Kallweit, Fugang Duan, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker On Tue, Mar 30, 2021 at 03:54:07PM +0200, Oleksij Rempel wrote: > 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 Hi Oleksij I've not done a side-by-side diff with stmmac, but i guess a lot of this code is identical? Rather than make a copy/paste, could you move it somewhere under net and turn it into a library any driver can use? Andrew ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 3/3] net: fec: add basic selftest support 2021-03-31 12:27 ` Andrew Lunn @ 2021-04-01 7:47 ` Oleksij Rempel 2021-04-01 16:06 ` Florian Fainelli 0 siblings, 1 reply; 12+ messages in thread From: Oleksij Rempel @ 2021-04-01 7:47 UTC (permalink / raw) To: Andrew Lunn Cc: Shawn Guo, Sascha Hauer, Florian Fainelli, Heiner Kallweit, Fugang Duan, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker On Wed, Mar 31, 2021 at 02:27:19PM +0200, Andrew Lunn wrote: > On Tue, Mar 30, 2021 at 03:54:07PM +0200, Oleksij Rempel wrote: > > 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 > > Hi > > Oleksij > > I've not done a side-by-side diff with stmmac, but i guess a lot of > this code is identical? ack > Rather than make a copy/paste, could you move > it somewhere under net and turn it into a library any driver can use? yes, I assume, it is possible to make this code complete generic for all devices, but we will need to provide some more call backs. For example enable MAC loop back, enable DSA loopbacks and so on. Do you have ideas for the new location of generic selftest code and where can be added loopback options for different levels? Regards, Oleksij -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v1 3/3] net: fec: add basic selftest support 2021-04-01 7:47 ` Oleksij Rempel @ 2021-04-01 16:06 ` Florian Fainelli 0 siblings, 0 replies; 12+ messages in thread From: Florian Fainelli @ 2021-04-01 16:06 UTC (permalink / raw) To: Oleksij Rempel, Andrew Lunn Cc: Shawn Guo, Sascha Hauer, Heiner Kallweit, Fugang Duan, kernel, netdev, linux-arm-kernel, linux-kernel, linux-imx, Fabio Estevam, David Jander, Russell King, Philippe Schenker On 4/1/21 12:47 AM, Oleksij Rempel wrote: > On Wed, Mar 31, 2021 at 02:27:19PM +0200, Andrew Lunn wrote: >> On Tue, Mar 30, 2021 at 03:54:07PM +0200, Oleksij Rempel wrote: >>> 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 >> >> Hi >> >> Oleksij >> >> I've not done a side-by-side diff with stmmac, but i guess a lot of >> this code is identical? > > ack > >> Rather than make a copy/paste, could you move >> it somewhere under net and turn it into a library any driver can use? > > yes, I assume, it is possible to make this code complete generic for all > devices, but we will need to provide some more call backs. For example > enable MAC loop back, enable DSA loopbacks and so on. > > Do you have ideas for the new location of generic selftest code and > where can be added loopback options for different levels? You could place the generic selftest code under net/core/ or net/ethernet. -- Florian ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-04-01 18:17 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-03-30 13:54 [PATCH net-next v1 0/3] provide basic selftest support for the ethernet FEC driver Oleksij Rempel 2021-03-30 13:54 ` [PATCH net-next v1 1/3] net: phy: micrel: KSZ8081: add loopback support Oleksij Rempel 2021-03-30 14:06 ` Marc Kleine-Budde 2021-03-30 14:39 ` Andrew Lunn 2021-03-30 13:54 ` [PATCH net-next v1 2/3] net: phy: at803x: AR8085: " Oleksij Rempel 2021-03-30 14:08 ` Marc Kleine-Budde 2021-03-30 14:49 ` Andrew Lunn 2021-03-30 13:54 ` [PATCH net-next v1 3/3] net: fec: add basic selftest support Oleksij Rempel 2021-03-31 1:07 ` kernel test robot 2021-03-31 12:27 ` Andrew Lunn 2021-04-01 7:47 ` Oleksij Rempel 2021-04-01 16:06 ` Florian Fainelli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).