Commit 8572aec3 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Add basic EST support for XGMAC



Adds the support for EST in XGMAC cores. This feature allows to offload
scheduling of queues opening time to the IP.

Signed-off-by: default avatarJose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 504723af
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@
#define XGMAC_HWFEAT_TXQCNT		GENMASK(9, 6)
#define XGMAC_HWFEAT_RXQCNT		GENMASK(3, 0)
#define XGMAC_HW_FEATURE3		0x00000128
#define XGMAC_HWFEAT_ESTWID		GENMASK(24, 23)
#define XGMAC_HWFEAT_ESTDEP		GENMASK(22, 20)
#define XGMAC_HWFEAT_ESTSEL		BIT(19)
#define XGMAC_HWFEAT_ASP		GENMASK(15, 14)
#define XGMAC_HWFEAT_DVLAN		BIT(13)
#define XGMAC_HWFEAT_FRPES		GENMASK(12, 11)
@@ -237,6 +240,22 @@
#define XGMAC_TC_PRTY_MAP1		0x00001044
#define XGMAC_PSTC(x)			GENMASK((x) * 8 + 7, (x) * 8)
#define XGMAC_PSTC_SHIFT(x)		((x) * 8)
#define XGMAC_MTL_EST_CONTROL		0x00001050
#define XGMAC_PTOV			GENMASK(31, 23)
#define XGMAC_PTOV_SHIFT		23
#define XGMAC_SSWL			BIT(1)
#define XGMAC_EEST			BIT(0)
#define XGMAC_MTL_EST_GCL_CONTROL	0x00001080
#define XGMAC_BTR_LOW			0x0
#define XGMAC_BTR_HIGH			0x1
#define XGMAC_CTR_LOW			0x2
#define XGMAC_CTR_HIGH			0x3
#define XGMAC_TER			0x4
#define XGMAC_LLR			0x5
#define XGMAC_ADDR_SHIFT		8
#define XGMAC_GCRR			BIT(2)
#define XGMAC_SRWO			BIT(0)
#define XGMAC_MTL_EST_GCL_DATA		0x00001084
#define XGMAC_MTL_RXP_CONTROL_STATUS	0x000010a0
#define XGMAC_RXPI			BIT(31)
#define XGMAC_NPE			GENMASK(23, 16)
+52 −0
Original line number Diff line number Diff line
@@ -1359,6 +1359,57 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
	writel(value, ioaddr + XGMAC_RX_CONFIG);
}

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

	writel(val, ioaddr + XGMAC_MTL_EST_GCL_DATA);

	ctrl = (reg << XGMAC_ADDR_SHIFT);
	ctrl |= gcl ? 0 : XGMAC_GCRR;

	writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);

	ctrl |= XGMAC_SRWO;
	writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);

	return readl_poll_timeout_atomic(ioaddr + XGMAC_MTL_EST_GCL_CONTROL,
					 ctrl, !(ctrl & XGMAC_SRWO), 100, 5000);
}

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

	ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false);
	ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false);
	ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false);
	ret |= dwxgmac3_est_write(ioaddr, XGMAC_LLR, cfg->gcl_size, false);
	ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_LOW, cfg->ctr[0], false);
	ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_HIGH, cfg->ctr[1], false);
	if (ret)
		return ret;

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

	ctrl = readl(ioaddr + XGMAC_MTL_EST_CONTROL);
	ctrl &= ~XGMAC_PTOV;
	ctrl |= ((1000000000 / ptp_rate) * 9) << XGMAC_PTOV_SHIFT;
	if (cfg->enable)
		ctrl |= XGMAC_EEST | XGMAC_SSWL;
	else
		ctrl &= ~XGMAC_EEST;

	writel(ctrl, ioaddr + XGMAC_MTL_EST_CONTROL);
	return 0;
}

const struct stmmac_ops dwxgmac210_ops = {
	.core_init = dwxgmac2_core_init,
	.set_mac = dwxgmac2_set_mac,
@@ -1402,6 +1453,7 @@ const struct stmmac_ops dwxgmac210_ops = {
	.config_l3_filter = dwxgmac2_config_l3_filter,
	.config_l4_filter = dwxgmac2_config_l4_filter,
	.set_arp_offload = dwxgmac2_set_arp_offload,
	.est_configure = dwxgmac3_est_configure,
};

int dwxgmac2_setup(struct stmmac_priv *priv)
+3 −0
Original line number Diff line number Diff line
@@ -429,6 +429,9 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,

	/* MAC HW feature 3 */
	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE3);
	dma_cap->estwid = (hw_cap & XGMAC_HWFEAT_ESTWID) >> 23;
	dma_cap->estdep = (hw_cap & XGMAC_HWFEAT_ESTDEP) >> 20;
	dma_cap->estsel = (hw_cap & XGMAC_HWFEAT_ESTSEL) >> 19;
	dma_cap->asp = (hw_cap & XGMAC_HWFEAT_ASP) >> 14;
	dma_cap->dvlan = (hw_cap & XGMAC_HWFEAT_DVLAN) >> 13;
	dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;