Commit c3f3b972 authored by Rohan G Thomas's avatar Rohan G Thomas Committed by Jakub Kicinski
Browse files

net: stmmac: Refactor EST implementation



Refactor EST implementation by moving common code for DWMAC4 and
DWXGMAC IPs into a separate EST module. EST implementation for DWMAC4
and DWXGMAC differs only for CSR base address, PTOV field offset
width, and PTOV clock multiplier value.

Thanks, Serge Semin and Jakub Kicinski for the suggestions on
refactoring EST implementation into a separate EST module.

Signed-off-by: default avatarRohan G Thomas <rohan.g.thomas@intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20231201055252.1302-3-rohan.g.thomas@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 58f3240b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
	      stmmac_xdp.o \
	      stmmac_xdp.o stmmac_est.o \
	      $(stmmac-y)

stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
+1 −0
Original line number Diff line number Diff line
@@ -563,6 +563,7 @@ struct mac_device_info {
	const struct stmmac_hwtimestamp *ptp;
	const struct stmmac_tc_ops *tc;
	const struct stmmac_mmc_ops *mmc;
	const struct stmmac_est_ops *est;
	struct dw_xpcs *xpcs;
	struct phylink_pcs *lynx_pcs; /* Lynx external PCS */
	struct mii_regs mii;	/* MII register Addresses */
+0 −4
Original line number Diff line number Diff line
@@ -1247,8 +1247,6 @@ const struct stmmac_ops dwmac410_ops = {
	.set_arp_offload = dwmac4_set_arp_offload,
	.config_l3_filter = dwmac4_config_l3_filter,
	.config_l4_filter = dwmac4_config_l4_filter,
	.est_configure = dwmac5_est_configure,
	.est_irq_status = dwmac5_est_irq_status,
	.fpe_configure = dwmac5_fpe_configure,
	.fpe_send_mpacket = dwmac5_fpe_send_mpacket,
	.fpe_irq_status = dwmac5_fpe_irq_status,
@@ -1302,8 +1300,6 @@ const struct stmmac_ops dwmac510_ops = {
	.set_arp_offload = dwmac4_set_arp_offload,
	.config_l3_filter = dwmac4_config_l3_filter,
	.config_l4_filter = dwmac4_config_l4_filter,
	.est_configure = dwmac5_est_configure,
	.est_irq_status = dwmac5_est_irq_status,
	.fpe_configure = dwmac5_fpe_configure,
	.fpe_send_mpacket = dwmac5_fpe_send_mpacket,
	.fpe_irq_status = dwmac5_fpe_irq_status,
+0 −137
Original line number Diff line number Diff line
@@ -573,143 +573,6 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
	return 0;
}

static int dwmac5_est_write(void __iomem *ioaddr, u32 reg, u32 val, bool gcl)
{
	u32 ctrl;

	writel(val, ioaddr + MTL_EST_GCL_DATA);

	ctrl = (reg << ADDR_SHIFT);
	ctrl |= gcl ? 0 : GCRR;

	writel(ctrl, ioaddr + MTL_EST_GCL_CONTROL);

	ctrl |= SRWO;
	writel(ctrl, ioaddr + MTL_EST_GCL_CONTROL);

	return readl_poll_timeout(ioaddr + MTL_EST_GCL_CONTROL,
				  ctrl, !(ctrl & SRWO), 100, 5000);
}

int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
			 unsigned int ptp_rate)
{
	int i, ret = 0x0;
	u32 ctrl;

	ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false);
	ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false);
	ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false);
	ret |= dwmac5_est_write(ioaddr, LLR, cfg->gcl_size, false);
	ret |= dwmac5_est_write(ioaddr, CTR_LOW, cfg->ctr[0], false);
	ret |= dwmac5_est_write(ioaddr, CTR_HIGH, cfg->ctr[1], false);
	if (ret)
		return ret;

	for (i = 0; i < cfg->gcl_size; i++) {
		ret = dwmac5_est_write(ioaddr, i, cfg->gcl[i], true);
		if (ret)
			return ret;
	}

	ctrl = readl(ioaddr + MTL_EST_CONTROL);
	ctrl &= ~PTOV;
	ctrl |= ((1000000000 / ptp_rate) * 6) << PTOV_SHIFT;
	if (cfg->enable)
		ctrl |= EEST | SSWL;
	else
		ctrl &= ~EEST;

	writel(ctrl, ioaddr + MTL_EST_CONTROL);

	/* Configure EST interrupt */
	if (cfg->enable)
		ctrl = (IECGCE | IEHS | IEHF | IEBE | IECC);
	else
		ctrl = 0;

	writel(ctrl, ioaddr + MTL_EST_INT_EN);

	return 0;
}

void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
			  struct stmmac_extra_stats *x, u32 txqcnt)
{
	u32 status, value, feqn, hbfq, hbfs, btrl;
	u32 txqcnt_mask = (1 << txqcnt) - 1;

	status = readl(ioaddr + MTL_EST_STATUS);

	value = (CGCE | HLBS | HLBF | BTRE | SWLC);

	/* Return if there is no error */
	if (!(status & value))
		return;

	if (status & CGCE) {
		/* Clear Interrupt */
		writel(CGCE, ioaddr + MTL_EST_STATUS);

		x->mtl_est_cgce++;
	}

	if (status & HLBS) {
		value = readl(ioaddr + MTL_EST_SCH_ERR);
		value &= txqcnt_mask;

		x->mtl_est_hlbs++;

		/* Clear Interrupt */
		writel(value, ioaddr + MTL_EST_SCH_ERR);

		/* Collecting info to shows all the queues that has HLBS
		 * issue. The only way to clear this is to clear the
		 * statistic
		 */
		if (net_ratelimit())
			netdev_err(dev, "EST: HLB(sched) Queue 0x%x\n", value);
	}

	if (status & HLBF) {
		value = readl(ioaddr + MTL_EST_FRM_SZ_ERR);
		feqn = value & txqcnt_mask;

		value = readl(ioaddr + MTL_EST_FRM_SZ_CAP);
		hbfq = (value & SZ_CAP_HBFQ_MASK(txqcnt)) >> SZ_CAP_HBFQ_SHIFT;
		hbfs = value & SZ_CAP_HBFS_MASK;

		x->mtl_est_hlbf++;

		/* Clear Interrupt */
		writel(feqn, ioaddr + MTL_EST_FRM_SZ_ERR);

		if (net_ratelimit())
			netdev_err(dev, "EST: HLB(size) Queue %u Size %u\n",
				   hbfq, hbfs);
	}

	if (status & BTRE) {
		if ((status & BTRL) == BTRL_MAX)
			x->mtl_est_btrlm++;
		else
			x->mtl_est_btre++;

		btrl = (status & BTRL) >> BTRL_SHIFT;

		if (net_ratelimit())
			netdev_info(dev, "EST: BTR Error Loop Count %u\n",
				    btrl);

		writel(BTRE, ioaddr + MTL_EST_STATUS);
	}

	if (status & SWLC) {
		writel(SWLC, ioaddr + MTL_EST_STATUS);
		netdev_info(dev, "EST: SWOL has been switched\n");
	}
}

void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
			  bool enable)
{
+0 −51
Original line number Diff line number Diff line
@@ -39,53 +39,6 @@
#define MAC_PPSx_INTERVAL(x)		(0x00000b88 + ((x) * 0x10))
#define MAC_PPSx_WIDTH(x)		(0x00000b8c + ((x) * 0x10))

#define MTL_EST_CONTROL			0x00000c50
#define PTOV				GENMASK(31, 24)
#define PTOV_SHIFT			24
#define SSWL				BIT(1)
#define EEST				BIT(0)

#define MTL_EST_STATUS			0x00000c58
#define BTRL				GENMASK(11, 8)
#define BTRL_SHIFT			8
#define BTRL_MAX			(0xF << BTRL_SHIFT)
#define SWOL				BIT(7)
#define SWOL_SHIFT			7
#define CGCE				BIT(4)
#define HLBS				BIT(3)
#define HLBF				BIT(2)
#define BTRE				BIT(1)
#define SWLC				BIT(0)

#define MTL_EST_SCH_ERR			0x00000c60
#define MTL_EST_FRM_SZ_ERR		0x00000c64
#define MTL_EST_FRM_SZ_CAP		0x00000c68
#define SZ_CAP_HBFS_MASK		GENMASK(14, 0)
#define SZ_CAP_HBFQ_SHIFT		16
#define SZ_CAP_HBFQ_MASK(_val)		({ typeof(_val) (val) = (_val);	\
					((val) > 4 ? GENMASK(18, 16) :	\
					 (val) > 2 ? GENMASK(17, 16) :	\
					 BIT(16)); })

#define MTL_EST_INT_EN			0x00000c70
#define IECGCE				CGCE
#define IEHS				HLBS
#define IEHF				HLBF
#define IEBE				BTRE
#define IECC				SWLC

#define MTL_EST_GCL_CONTROL		0x00000c80
#define BTR_LOW				0x0
#define BTR_HIGH			0x1
#define CTR_LOW				0x2
#define CTR_HIGH			0x3
#define TER				0x4
#define LLR				0x5
#define ADDR_SHIFT			8
#define GCRR				BIT(2)
#define SRWO				BIT(0)
#define MTL_EST_GCL_DATA		0x00000c84

#define MTL_RXP_CONTROL_STATUS		0x00000ca0
#define RXPI				BIT(31)
#define NPE				GENMASK(23, 16)
@@ -149,10 +102,6 @@ int dwmac5_rxp_config(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
			   struct stmmac_pps_cfg *cfg, bool enable,
			   u32 sub_second_inc, u32 systime_flags);
int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
			 unsigned int ptp_rate);
void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
			   struct stmmac_extra_stats *x, u32 txqcnt);
void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
			  bool enable);
void dwmac5_fpe_send_mpacket(void __iomem *ioaddr,
Loading