Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b30842b authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller
Browse files

net: fec: Clear and enable MIB counters on imx51



Both the IMX51 and IMX53 datasheet indicates that the MIB counters
should be cleared during setup. Otherwise random numbers are returned
via ethtool -S.  Add a quirk and a function to do this.

Tested on an IMX51.

Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarFabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 216fe8f0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -446,6 +446,10 @@ struct bufdesc_ex {
#define FEC_QUIRK_HAS_COALESCE		(1 << 13)
/* Interrupt doesn't wake CPU from deep idle */
#define FEC_QUIRK_ERR006687		(1 << 14)
/* The MIB counters should be cleared and enabled during
 * initialisation.
 */
#define FEC_QUIRK_MIB_CLEAR		(1 << 15)

struct bufdesc_prop {
	int qid;
+24 −3
Original line number Diff line number Diff line
@@ -89,10 +89,10 @@ static struct platform_device_id fec_devtype[] = {
		.driver_data = 0,
	}, {
		.name = "imx25-fec",
		.driver_data = FEC_QUIRK_USE_GASKET,
		.driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR,
	}, {
		.name = "imx27-fec",
		.driver_data = 0,
		.driver_data = FEC_QUIRK_MIB_CLEAR,
	}, {
		.name = "imx28-fec",
		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
@@ -184,6 +184,9 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
#define FEC_RACC_SHIFT16	BIT(7)
#define FEC_RACC_OPTIONS	(FEC_RACC_IPDIS | FEC_RACC_PRODIS)

/* MIB Control Register */
#define FEC_MIB_CTRLSTAT_DISABLE	BIT(31)

/*
 * The 5270/5271/5280/5282/532x RX control register also contains maximum frame
 * size bits. Other FEC hardware does not, so we need to take that into
@@ -2356,6 +2359,21 @@ static int fec_enet_get_sset_count(struct net_device *dev, int sset)
	}
}

static void fec_enet_clear_ethtool_stats(struct net_device *dev)
{
	struct fec_enet_private *fep = netdev_priv(dev);
	int i;

	/* Disable MIB statistics counters */
	writel(FEC_MIB_CTRLSTAT_DISABLE, fep->hwp + FEC_MIB_CTRLSTAT);

	for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
		writel(0, fep->hwp + fec_stats[i].offset);

	/* Don't disable MIB statistics counters */
	writel(0, fep->hwp + FEC_MIB_CTRLSTAT);
}

#else	/* !defined(CONFIG_M5272) */
#define FEC_STATS_SIZE	0
static inline void fec_enet_update_ethtool_stats(struct net_device *dev)
@@ -3182,6 +3200,9 @@ static int fec_enet_init(struct net_device *ndev)

	fec_restart(ndev);

	if (fep->quirks & FEC_QUIRK_MIB_CLEAR)
		fec_enet_clear_ethtool_stats(ndev);
	else
		fec_enet_update_ethtool_stats(ndev);

	return 0;