Commit 39983de5 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-fec-general-vlan-cleanups'

Marc Kleine-Budde says:

====================
net: fec: general + VLAN cleanups

This series first cleans up the fec driver a bit (typos, obsolete
comments, add missing header files, rename struct, replace magic
number by defines).

The last 5 patches clean up the fec_enet_rx_queue() function,
including VLAN handling.

v3: https://patch.msgid.link/20250617-fec-cleanups-v3-0-a57bfb38993f@pengutronix.de
v2: https://patch.msgid.link/20250612-fec-cleanups-v2-0-ae7c36df185e@pengutronix.de
v1: https://patch.msgid.link/20241016-fec-cleanups-v1-0-de783bd15e6a@pengutronix.de
====================

Link: https://patch.msgid.link/20250618-fec-cleanups-v4-0-c16f9a1af124@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 9ce3f34c 0593f8df
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -14,14 +14,14 @@
#define	FEC_H
/****************************************************************************/

#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/bpf.h>
#include <linux/clocksource.h>
#include <linux/firmware/imx/sci.h>
#include <linux/net_tstamp.h>
#include <linux/pm_qos.h>
#include <linux/bpf.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/firmware/imx/sci.h>
#include <net/xdp.h>

#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
@@ -115,7 +115,7 @@
#define IEEE_T_MCOL		0x254 /* Frames tx'd with multiple collision */
#define IEEE_T_DEF		0x258 /* Frames tx'd after deferral delay */
#define IEEE_T_LCOL		0x25c /* Frames tx'd with late collision */
#define IEEE_T_EXCOL		0x260 /* Frames tx'd with excesv collisions */
#define IEEE_T_EXCOL		0x260 /* Frames tx'd with excessive collisions */
#define IEEE_T_MACERR		0x264 /* Frames tx'd with TX FIFO underrun */
#define IEEE_T_CSERR		0x268 /* Frames tx'd with carrier sense err */
#define IEEE_T_SQE		0x26c /* Frames tx'd with SQE err */
@@ -342,7 +342,7 @@ struct bufdesc_ex {
#define FEC_TX_BD_FTYPE(X)	(((X) & 0xf) << 20)

/* The number of Tx and Rx buffers.  These are allocated from the page
 * pool.  The code may assume these are power of two, so it it best
 * pool.  The code may assume these are power of two, so it is best
 * to keep them that size.
 * We don't need to allocate pages for the transmitter.  We just use
 * the skbuffer directly.
@@ -460,7 +460,7 @@ struct bufdesc_ex {
#define FEC_QUIRK_SINGLE_MDIO		(1 << 11)
/* Controller supports RACC register */
#define FEC_QUIRK_HAS_RACC		(1 << 12)
/* Controller supports interrupt coalesc */
/* Controller supports interrupt coalesce */
#define FEC_QUIRK_HAS_COALESCE		(1 << 13)
/* Interrupt doesn't wake CPU from deep idle */
#define FEC_QUIRK_ERR006687		(1 << 14)
@@ -495,7 +495,7 @@ struct bufdesc_ex {
 */
#define FEC_QUIRK_HAS_EEE		(1 << 20)

/* i.MX8QM ENET IP version add new feture to generate delayed TXC/RXC
/* i.MX8QM ENET IP version add new feature to generate delayed TXC/RXC
 * as an alternative option to make sure it works well with various PHYs.
 * For the implementation of delayed clock, ENET takes synchronized 250MHz
 * clocks to generate 2ns delay.
@@ -614,7 +614,6 @@ struct fec_enet_private {
	unsigned int num_tx_queues;
	unsigned int num_rx_queues;

	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
	struct fec_enet_priv_tx_q *tx_queue[FEC_ENET_MAX_TX_QS];
	struct fec_enet_priv_rx_q *rx_queue[FEC_ENET_MAX_RX_QS];

+63 −66
Original line number Diff line number Diff line
@@ -22,56 +22,55 @@
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/pm_runtime.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/cacheflush.h>
#include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <net/page_pool/helpers.h>
#include <net/selftests.h>
#include <net/tso.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/fec.h>
#include <linux/filter.h>
#include <linux/gpio/consumer.h>
#include <linux/icmp.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
#include <linux/in.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/ip.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/kernel.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/fec.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/regulator/consumer.h>
#include <linux/if_vlan.h>
#include <linux/phy.h>
#include <linux/pinctrl/consumer.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/prefetch.h>
#include <linux/mfd/syscon.h>
#include <linux/property.h>
#include <linux/ptrace.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/workqueue.h>
#include <net/ip.h>
#include <net/page_pool/helpers.h>
#include <net/selftests.h>
#include <net/tso.h>
#include <soc/imx/cpuidle.h>
#include <linux/filter.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>

#include <asm/cacheflush.h>

#include "fec.h"

@@ -131,7 +130,7 @@ static const struct fec_devinfo fec_mvf600_info = {
		  FEC_QUIRK_HAS_MDIO_C45,
};

static const struct fec_devinfo fec_imx6x_info = {
static const struct fec_devinfo fec_imx6sx_info = {
	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
@@ -196,7 +195,7 @@ static const struct of_device_id fec_dt_ids[] = {
	{ .compatible = "fsl,imx28-fec", .data = &fec_imx28_info, },
	{ .compatible = "fsl,imx6q-fec", .data = &fec_imx6q_info, },
	{ .compatible = "fsl,mvf600-fec", .data = &fec_mvf600_info, },
	{ .compatible = "fsl,imx6sx-fec", .data = &fec_imx6x_info, },
	{ .compatible = "fsl,imx6sx-fec", .data = &fec_imx6sx_info, },
	{ .compatible = "fsl,imx6ul-fec", .data = &fec_imx6ul_info, },
	{ .compatible = "fsl,imx8mq-fec", .data = &fec_imx8mq_info, },
	{ .compatible = "fsl,imx8qm-fec", .data = &fec_imx8qm_info, },
@@ -276,6 +275,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
#define FEC_ECR_MAGICEN         BIT(2)
#define FEC_ECR_SLEEP           BIT(3)
#define FEC_ECR_EN1588          BIT(4)
#define FEC_ECR_SPEED           BIT(5)
#define FEC_ECR_BYTESWP         BIT(8)
/* FEC RCR bits definition */
#define FEC_RCR_LOOP            BIT(0)
@@ -1207,7 +1207,7 @@ fec_restart(struct net_device *ndev)
		/* 1G, 100M or 10M */
		if (ndev->phydev) {
			if (ndev->phydev->speed == SPEED_1000)
				ecntl |= (1 << 5);
				ecntl |= FEC_ECR_SPEED;
			else if (ndev->phydev->speed == SPEED_100)
				rcntl &= ~FEC_RCR_10BASET;
			else
@@ -1706,13 +1706,29 @@ fec_enet_run_xdp(struct fec_enet_private *fep, struct bpf_prog *prog,
	return ret;
}

static void fec_enet_rx_vlan(const struct net_device *ndev, struct sk_buff *skb)
{
	if (ndev->features & NETIF_F_HW_VLAN_CTAG_RX) {
		const struct vlan_ethhdr *vlan_header = skb_vlan_eth_hdr(skb);
		const u16 vlan_tag = ntohs(vlan_header->h_vlan_TCI);

		/* Push and remove the vlan tag */

		memmove(skb->data + VLAN_HLEN, skb->data, ETH_ALEN * 2);
		skb_pull(skb, VLAN_HLEN);
		__vlan_hwaccel_put_tag(skb,
				       htons(ETH_P_8021Q),
				       vlan_tag);
	}
}

/* During a receive, the bd_rx.cur points to the current incoming buffer.
 * When we update through the ring, if the next incoming buffer has
 * not been given to the system, we just set the empty indicator,
 * effectively tossing the packet.
 */
static int
fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
fec_enet_rx_queue(struct net_device *ndev, u16 queue_id, int budget)
{
	struct fec_enet_private *fep = netdev_priv(ndev);
	struct fec_enet_priv_rx_q *rxq;
@@ -1720,11 +1736,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
	unsigned short status;
	struct  sk_buff *skb;
	ushort	pkt_len;
	__u8 *data;
	int	pkt_received = 0;
	struct	bufdesc_ex *ebdp = NULL;
	bool	vlan_packet_rcvd = false;
	u16	vlan_tag;
	int	index = 0;
	bool	need_swap = fep->quirks & FEC_QUIRK_SWAP_FRAME;
	struct bpf_prog *xdp_prog = READ_ONCE(fep->xdp_prog);
@@ -1843,10 +1856,11 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
		skb_mark_for_recycle(skb);

		if (unlikely(need_swap)) {
			u8 *data;

			data = page_address(page) + FEC_ENET_XDP_HEADROOM;
			swap_buffer(data, pkt_len);
		}
		data = skb->data;

		/* Extract the enhanced buffer descriptor */
		ebdp = NULL;
@@ -1854,20 +1868,9 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
			ebdp = (struct bufdesc_ex *)bdp;

		/* If this is a VLAN packet remove the VLAN Tag */
		vlan_packet_rcvd = false;
		if ((ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
		    fep->bufdesc_ex &&
		    (ebdp->cbd_esc & cpu_to_fec32(BD_ENET_RX_VLAN))) {
			/* Push and remove the vlan tag */
			struct vlan_hdr *vlan_header =
					(struct vlan_hdr *) (data + ETH_HLEN);
			vlan_tag = ntohs(vlan_header->h_vlan_TCI);

			vlan_packet_rcvd = true;

			memmove(skb->data + VLAN_HLEN, data, ETH_ALEN * 2);
			skb_pull(skb, VLAN_HLEN);
		}
		if (fep->bufdesc_ex &&
		    (ebdp->cbd_esc & cpu_to_fec32(BD_ENET_RX_VLAN)))
			fec_enet_rx_vlan(ndev, skb);

		skb->protocol = eth_type_trans(skb, ndev);

@@ -1886,12 +1889,6 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
			}
		}

		/* Handle received VLAN packets */
		if (vlan_packet_rcvd)
			__vlan_hwaccel_put_tag(skb,
					       htons(ETH_P_8021Q),
					       vlan_tag);

		skb_record_rx_queue(skb, queue_id);
		napi_gro_receive(&fep->napi, skb);

@@ -1939,7 +1936,7 @@ static int fec_enet_rx(struct net_device *ndev, int budget)

	/* Make sure that AVB queues are processed first. */
	for (i = fep->num_rx_queues - 1; i >= 0; i--)
		done += fec_enet_rx_queue(ndev, budget - done, i);
		done += fec_enet_rx_queue(ndev, i, budget - done);

	return done;
}
+1 −1
Original line number Diff line number Diff line
@@ -619,7 +619,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
	out_be32(&fec->rfifo_alarm, 0x0000030c);
	out_be32(&fec->tfifo_alarm, 0x00000100);

	/* begin transmittion when 256 bytes are in FIFO (or EOF or FIFO full) */
	/* begin transmission when 256 bytes are in FIFO (or EOF or FIFO full) */
	out_be32(&fec->x_wmrk, FEC_FIFO_WMRK_256B);

	/* enable crc generation */
+20 −20
Original line number Diff line number Diff line
@@ -7,30 +7,30 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
#include <linux/fec.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/fec.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/pci.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/ptrace.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/workqueue.h>

#include "fec.h"

@@ -117,7 +117,7 @@ static u64 fec_ptp_read(const struct cyclecounter *cc)
 * @fep: the fec_enet_private structure handle
 * @enable: enable the channel pps output
 *
 * This function enble the PPS ouput on the timer channel.
 * This function enables the PPS output on the timer channel.
 */
static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
{
@@ -172,7 +172,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
		 * very close to the second point, which means NSEC_PER_SEC
		 * - ts.tv_nsec is close to be zero(For example 20ns); Since the timer
		 * is still running when we calculate the first compare event, it is
		 * possible that the remaining nanoseonds run out before the compare
		 * possible that the remaining nanoseconds run out before the compare
		 * counter is calculated and written into TCCR register. To avoid
		 * this possibility, we will set the compare event to be the next
		 * of next second. The current setting is 31-bit timer and wrap