Commit a9ce2ce1 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'add-more-features-for-enetc-v4-round-2'

Wei Fang says:

====================
Add more features for ENETC v4 - round 2

This patch set adds the following features.
1. Compared with ENETC v1, the formats of tables and command BD of ENETC
v4 have changed significantly, and the two are not compatible. Therefore,
in order to support the NETC Table Management Protocol (NTMP) v2.0, we
introduced the netc-lib driver and added support for MAC address filter
table and RSS table.
2. Add MAC filter and VLAN filter support for i.MX95 ENETC PF.
3. Add RSS support for i.MX95 ENETC PF.
4. Add loopback support for i.MX95 ENETC PF.

v1: Link: https://lore.kernel.org/20250103060610.2233908-1-wei.fang@nxp.com/
v2: Link: https://lore.kernel.org/20250113082245.2332775-1-wei.fang@nxp.com/
v3: Link: https://lore.kernel.org/20250304072201.1332603-1-wei.fang@nxp.com/
v4: Link: https://lore.kernel.org/20250311053830.1516523-1-wei.fang@nxp.com/
v5: Link: https://lore.kernel.org/20250411095752.3072696-1-wei.fang@nxp.com/
v6: Link: https://lore.kernel.org/20250428105657.3283130-1-wei.fang@nxp.com/
====================

Link: https://patch.msgid.link/20250506080735.3444381-1-wei.fang@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d97e2634 932ce980
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9378,6 +9378,7 @@ F: Documentation/devicetree/bindings/net/nxp,netc-blk-ctrl.yaml
F:	drivers/net/ethernet/freescale/enetc/
F:	include/linux/fsl/enetc_mdio.h
F:	include/linux/fsl/netc_global.h
F:	include/linux/fsl/ntmp.h
FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
M:	Claudiu Manoil <claudiu.manoil@nxp.com>
+8 −0
Original line number Diff line number Diff line
@@ -15,6 +15,13 @@ config NXP_ENETC_PF_COMMON

	  If compiled as module (M), the module name is nxp-enetc-pf-common.

config NXP_NETC_LIB
	tristate
	help
	  This module provides common functionalities for both ENETC and NETC
	  Switch, such as NETC Table Management Protocol (NTMP) 2.0, common tc
	  flower and debugfs interfaces and so on.

config FSL_ENETC
	tristate "ENETC PF driver"
	depends on PCI_MSI
@@ -40,6 +47,7 @@ config NXP_ENETC4
	select FSL_ENETC_CORE
	select FSL_ENETC_MDIO
	select NXP_ENETC_PF_COMMON
	select NXP_NETC_LIB
	select PHYLINK
	select DIMLIB
	help
+4 −0
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@ fsl-enetc-core-y := enetc.o enetc_cbdr.o enetc_ethtool.o
obj-$(CONFIG_NXP_ENETC_PF_COMMON) += nxp-enetc-pf-common.o
nxp-enetc-pf-common-y := enetc_pf_common.o

obj-$(CONFIG_NXP_NETC_LIB) += nxp-netc-lib.o
nxp-netc-lib-y := ntmp.o

obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o
fsl-enetc-y := enetc_pf.o
fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
@@ -13,6 +16,7 @@ fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o

obj-$(CONFIG_NXP_ENETC4) += nxp-enetc4.o
nxp-enetc4-y := enetc4_pf.o
nxp-enetc4-$(CONFIG_DEBUG_FS) += enetc4_debugfs.o

obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o
fsl-enetc-vf-y := enetc_vf.o
+55 −21
Original line number Diff line number Diff line
@@ -36,6 +36,42 @@ static void enetc_change_preemptible_tcs(struct enetc_ndev_priv *priv,
	enetc_mm_commit_preemptible_tcs(priv);
}

static int enetc_mac_addr_hash_idx(const u8 *addr)
{
	u64 fold = __swab64(ether_addr_to_u64(addr)) >> 16;
	u64 mask = 0;
	int res = 0;
	int i;

	for (i = 0; i < 8; i++)
		mask |= BIT_ULL(i * 6);

	for (i = 0; i < 6; i++)
		res |= (hweight64(fold & (mask << i)) & 0x1) << i;

	return res;
}

void enetc_add_mac_addr_ht_filter(struct enetc_mac_filter *filter,
				  const unsigned char *addr)
{
	int idx = enetc_mac_addr_hash_idx(addr);

	/* add hash table entry */
	__set_bit(idx, filter->mac_hash_table);
	filter->mac_addr_cnt++;
}
EXPORT_SYMBOL_GPL(enetc_add_mac_addr_ht_filter);

void enetc_reset_mac_addr_filter(struct enetc_mac_filter *filter)
{
	filter->mac_addr_cnt = 0;

	bitmap_zero(filter->mac_hash_table,
		    ENETC_MADDR_HASH_TBL_SZ);
}
EXPORT_SYMBOL_GPL(enetc_reset_mac_addr_filter);

static int enetc_num_stack_tx_queues(struct enetc_ndev_priv *priv)
{
	int num_tx_rings = priv->num_tx_rings;
@@ -2379,7 +2415,7 @@ static int enetc_setup_default_rss_table(struct enetc_si *si, int num_groups)
	for (i = 0; i < si->num_rss; i++)
		rss_table[i] = i % num_groups;

	enetc_set_rss_table(si, rss_table, si->num_rss);
	si->ops->set_rss_table(si, rss_table, si->num_rss);

	kfree(rss_table);

@@ -2394,6 +2430,20 @@ static void enetc_set_lso_flags_mask(struct enetc_hw *hw)
	enetc_wr(hw, ENETC4_SILSOSFMR1, 0);
}

static void enetc_set_rss(struct net_device *ndev, int en)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
	struct enetc_hw *hw = &priv->si->hw;
	u32 reg;

	enetc_wr(hw, ENETC_SIRBGCR, priv->num_rx_rings);

	reg = enetc_rd(hw, ENETC_SIMR);
	reg &= ~ENETC_SIMR_RSSE;
	reg |= (en) ? ENETC_SIMR_RSSE : 0;
	enetc_wr(hw, ENETC_SIMR, reg);
}

int enetc_configure_si(struct enetc_ndev_priv *priv)
{
	struct enetc_si *si = priv->si;
@@ -2410,13 +2460,13 @@ int enetc_configure_si(struct enetc_ndev_priv *priv)
	if (si->hw_features & ENETC_SI_F_LSO)
		enetc_set_lso_flags_mask(hw);

	/* TODO: RSS support for i.MX95 will be supported later, and the
	 * is_enetc_rev1() condition will be removed
	 */
	if (si->num_rss && is_enetc_rev1(si)) {
	if (si->num_rss) {
		err = enetc_setup_default_rss_table(si, priv->num_rx_rings);
		if (err)
			return err;

		if (priv->ndev->features & NETIF_F_RXHASH)
			enetc_set_rss(priv->ndev, true);
	}

	return 0;
@@ -3209,22 +3259,6 @@ struct net_device_stats *enetc_get_stats(struct net_device *ndev)
}
EXPORT_SYMBOL_GPL(enetc_get_stats);

static int enetc_set_rss(struct net_device *ndev, int en)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
	struct enetc_hw *hw = &priv->si->hw;
	u32 reg;

	enetc_wr(hw, ENETC_SIRBGCR, priv->num_rx_rings);

	reg = enetc_rd(hw, ENETC_SIMR);
	reg &= ~ENETC_SIMR_RSSE;
	reg |= (en) ? ENETC_SIMR_RSSE : 0;
	enetc_wr(hw, ENETC_SIMR, reg);

	return 0;
}

static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+43 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/dma-mapping.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/fsl/ntmp.h>
#include <linux/if_vlan.h>
#include <linux/phylink.h>
#include <linux/dim.h>
@@ -22,6 +23,18 @@

#define ENETC_CBD_DATA_MEM_ALIGN 64

#define ENETC_MADDR_HASH_TBL_SZ	64

enum enetc_mac_addr_type {UC, MC, MADDR_TYPE};

struct enetc_mac_filter {
	union {
		char mac_addr[ETH_ALEN];
		DECLARE_BITMAP(mac_hash_table, ENETC_MADDR_HASH_TBL_SZ);
	};
	int mac_addr_cnt;
};

struct enetc_tx_swbd {
	union {
		struct sk_buff *skb;
@@ -266,6 +279,19 @@ struct enetc_platform_info {
	const struct enetc_drvdata *data;
};

struct enetc_si;

/*
 * This structure defines the some common hooks for ENETC PSI and VSI.
 * In addition, since VSI only uses the struct enetc_si as its private
 * driver data, so this structure also define some hooks specifically
 * for VSI. For VSI-specific hooks, the format is ‘vf_*()’.
 */
struct enetc_si_ops {
	int (*get_rss_table)(struct enetc_si *si, u32 *table, int count);
	int (*set_rss_table)(struct enetc_si *si, const u32 *table, int count);
};

/* PCI IEP device data */
struct enetc_si {
	struct pci_dev *pdev;
@@ -274,7 +300,10 @@ struct enetc_si {

	struct net_device *ndev; /* back ref. */

	struct enetc_cbdr cbd_ring;
	union {
		struct enetc_cbdr cbd_ring; /* Only ENETC 1.0 */
		struct ntmp_user ntmp_user; /* ENETC 4.1 and later */
	};

	int num_rx_rings; /* how many rings are available in the SI */
	int num_tx_rings;
@@ -284,6 +313,11 @@ struct enetc_si {
	u16 revision;
	int hw_features;
	const struct enetc_drvdata *drvdata;
	const struct enetc_si_ops *ops;

	struct workqueue_struct *workqueue;
	struct work_struct rx_mode_task;
	struct dentry *debugfs_root;
};

#define ENETC_SI_ALIGN	32
@@ -466,6 +500,9 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv);
void enetc_free_si_resources(struct enetc_ndev_priv *priv);
int enetc_configure_si(struct enetc_ndev_priv *priv);
int enetc_get_driver_data(struct enetc_si *si);
void enetc_add_mac_addr_ht_filter(struct enetc_mac_filter *filter,
				  const unsigned char *addr);
void enetc_reset_mac_addr_filter(struct enetc_mac_filter *filter);

int enetc_open(struct net_device *ndev);
int enetc_close(struct net_device *ndev);
@@ -493,15 +530,19 @@ void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);
int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
		     struct enetc_cbdr *cbdr);
void enetc_teardown_cbdr(struct enetc_cbdr *cbdr);
int enetc4_setup_cbdr(struct enetc_si *si);
void enetc4_teardown_cbdr(struct enetc_si *si);
int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
			    char *mac_addr, int si_map);
int enetc_clear_mac_flt_entry(struct enetc_si *si, int index);
int enetc_set_fs_entry(struct enetc_si *si, struct enetc_cmd_rfse *rfse,
		       int index);
void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes);
void enetc_set_rss_key(struct enetc_si *si, const u8 *bytes);
int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count);
int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count);
int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);
int enetc4_get_rss_table(struct enetc_si *si, u32 *table, int count);
int enetc4_set_rss_table(struct enetc_si *si, const u32 *table, int count);

static inline void *enetc_cbd_alloc_data_mem(struct enetc_si *si,
					     struct enetc_cbd *cbd,
Loading