Commit 02c97223 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-stmmac-yet-more-eee-updates'

Russell King says:

====================
net: stmmac: yet more EEE updates

Continuing on with the STMMAC EEE cleanups from last cycle, this series
further cleans up the EEE code, and fixes a problem with the existing
implementation - disabling EEE doesn't immediately disable LPI
signalling until the next packet is transmitted. It likely also fixes
a potential race condition when trying to disable LPI vs the software
timer.
====================

Link: https://patch.msgid.link/Z6NqGnM2yL7Ayo-T@shell.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents be258f65 62b0a039
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -530,6 +530,20 @@ struct dma_features {
#define STMMAC_DEFAULT_TWT_LS	0x1E
#define STMMAC_ET_MAX		0xFFFFF

/* Common LPI register bits */
#define LPI_CTRL_STATUS_LPITCSE	BIT(21)	/* LPI Tx Clock Stop Enable, gmac4, xgmac2 only */
#define LPI_CTRL_STATUS_LPIATE	BIT(20)	/* LPI Timer Enable, gmac4 only */
#define LPI_CTRL_STATUS_LPITXA	BIT(19)	/* Enable LPI TX Automate */
#define LPI_CTRL_STATUS_PLSEN	BIT(18)	/* Enable PHY Link Status */
#define LPI_CTRL_STATUS_PLS	BIT(17)	/* PHY Link Status */
#define LPI_CTRL_STATUS_LPIEN	BIT(16)	/* LPI Enable */
#define LPI_CTRL_STATUS_RLPIST	BIT(9)	/* Receive LPI state, gmac1000 only? */
#define LPI_CTRL_STATUS_TLPIST	BIT(8)	/* Transmit LPI state, gmac1000 only? */
#define LPI_CTRL_STATUS_RLPIEX	BIT(3)	/* Receive LPI Exit */
#define LPI_CTRL_STATUS_RLPIEN	BIT(2)	/* Receive LPI Entry */
#define LPI_CTRL_STATUS_TLPIEX	BIT(1)	/* Transmit LPI Exit */
#define LPI_CTRL_STATUS_TLPIEN	BIT(0)	/* Transmit LPI Entry */

#define STMMAC_CHAIN_MODE	0x1
#define STMMAC_RING_MODE	0x2

+1 −12
Original line number Diff line number Diff line
@@ -59,22 +59,11 @@ enum power_event {
/* Energy Efficient Ethernet (EEE)
 *
 * LPI status, timer and control register offset
 * For LPI control and status bit definitions, see common.h.
 */
#define LPI_CTRL_STATUS	0x0030
#define LPI_TIMER_CTRL	0x0034

/* LPI control and status defines */
#define LPI_CTRL_STATUS_LPITXA	0x00080000	/* Enable LPI TX Automate */
#define LPI_CTRL_STATUS_PLSEN	0x00040000	/* Enable PHY Link Status */
#define LPI_CTRL_STATUS_PLS	0x00020000	/* PHY Link Status */
#define LPI_CTRL_STATUS_LPIEN	0x00010000	/* LPI Enable */
#define LPI_CTRL_STATUS_RLPIST	0x00000200	/* Receive LPI state */
#define LPI_CTRL_STATUS_TLPIST	0x00000100	/* Transmit LPI state */
#define LPI_CTRL_STATUS_RLPIEX	0x00000008	/* Receive LPI Exit */
#define LPI_CTRL_STATUS_RLPIEN	0x00000004	/* Receive LPI Entry */
#define LPI_CTRL_STATUS_TLPIEX	0x00000002	/* Transmit LPI Exit */
#define LPI_CTRL_STATUS_TLPIEN	0x00000001	/* Transmit LPI Entry */

/* GMAC HW ADDR regs */
#define GMAC_ADDR_HIGH(reg)	((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \
				 0x00000040 + (reg * 8))
+11 −19
Original line number Diff line number Diff line
@@ -342,31 +342,24 @@ static int dwmac1000_irq_status(struct mac_device_info *hw,
	return ret;
}

static void dwmac1000_set_eee_mode(struct mac_device_info *hw,
				   bool en_tx_lpi_clockgating)
static int dwmac1000_set_lpi_mode(struct mac_device_info *hw,
				  enum stmmac_lpi_mode mode,
				  bool en_tx_lpi_clockgating, u32 et)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	/*TODO - en_tx_lpi_clockgating treatment */
	if (mode == STMMAC_LPI_TIMER)
		return -EOPNOTSUPP;

	/* Enable the link status receive on RGMII, SGMII ore SMII
	 * receive path and instruct the transmit to enter in LPI
	 * state.
	 */
	value = readl(ioaddr + LPI_CTRL_STATUS);
	if (mode == STMMAC_LPI_FORCED)
		value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
	writel(value, ioaddr + LPI_CTRL_STATUS);
}

static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + LPI_CTRL_STATUS);
	else
		value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
	writel(value, ioaddr + LPI_CTRL_STATUS);

	return 0;
}

static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
@@ -509,8 +502,7 @@ const struct stmmac_ops dwmac1000_ops = {
	.pmt = dwmac1000_pmt,
	.set_umac_addr = dwmac1000_set_umac_addr,
	.get_umac_addr = dwmac1000_get_umac_addr,
	.set_eee_mode = dwmac1000_set_eee_mode,
	.reset_eee_mode = dwmac1000_reset_eee_mode,
	.set_lpi_mode = dwmac1000_set_lpi_mode,
	.set_eee_timer = dwmac1000_set_eee_timer,
	.set_eee_pls = dwmac1000_set_eee_pls,
	.debug = dwmac1000_debug,
+1 −11
Original line number Diff line number Diff line
@@ -177,23 +177,13 @@ enum power_event {
/* Energy Efficient Ethernet (EEE) for GMAC4
 *
 * LPI status, timer and control register offset
 * For LPI control and status bit definitions, see common.h.
 */
#define GMAC4_LPI_CTRL_STATUS	0xd0
#define GMAC4_LPI_TIMER_CTRL	0xd4
#define GMAC4_LPI_ENTRY_TIMER	0xd8
#define GMAC4_MAC_ONEUS_TIC_COUNTER	0xdc

/* LPI control and status defines */
#define GMAC4_LPI_CTRL_STATUS_LPITCSE	BIT(21)	/* LPI Tx Clock Stop Enable */
#define GMAC4_LPI_CTRL_STATUS_LPIATE	BIT(20) /* LPI Timer Enable */
#define GMAC4_LPI_CTRL_STATUS_LPITXA	BIT(19)	/* Enable LPI TX Automate */
#define GMAC4_LPI_CTRL_STATUS_PLS	BIT(17) /* PHY Link Status */
#define GMAC4_LPI_CTRL_STATUS_LPIEN	BIT(16)	/* LPI Enable */
#define GMAC4_LPI_CTRL_STATUS_RLPIEX	BIT(3) /* Receive LPI Exit */
#define GMAC4_LPI_CTRL_STATUS_RLPIEN	BIT(2) /* Receive LPI Entry */
#define GMAC4_LPI_CTRL_STATUS_TLPIEX	BIT(1) /* Transmit LPI Exit */
#define GMAC4_LPI_CTRL_STATUS_TLPIEN	BIT(0) /* Transmit LPI Entry */

/* MAC Debug bitmap */
#define GMAC_DEBUG_TFCSTS_MASK		GENMASK(18, 17)
#define GMAC_DEBUG_TFCSTS_SHIFT		17
+41 −55
Original line number Diff line number Diff line
@@ -376,33 +376,46 @@ static void dwmac4_get_umac_addr(struct mac_device_info *hw,
				   GMAC_ADDR_LOW(reg_n));
}

static void dwmac4_set_eee_mode(struct mac_device_info *hw,
				bool en_tx_lpi_clockgating)
static int dwmac4_set_lpi_mode(struct mac_device_info *hw,
			       enum stmmac_lpi_mode mode,
			       bool en_tx_lpi_clockgating, u32 et)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;
	u32 value, mask;

	if (mode == STMMAC_LPI_DISABLE) {
		value = 0;
	} else {
		value = LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;

	/* Enable the link status receive on RGMII, SGMII ore SMII
	 * receive path and instruct the transmit to enter in LPI
	 * state.
		if (mode == STMMAC_LPI_TIMER) {
			/* Return ERANGE if the timer is larger than the
			 * register field.
			 */
	value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
	value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA;
			if (et > STMMAC_ET_MAX)
				return -ERANGE;

	if (en_tx_lpi_clockgating)
		value |= GMAC4_LPI_CTRL_STATUS_LPITCSE;
			/* Set the hardware LPI entry timer */
			writel(et, ioaddr + GMAC4_LPI_ENTRY_TIMER);

	writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
			/* Interpret a zero LPI entry timer to mean
			 * immediate entry into LPI mode.
			 */
			if (et)
				value |= LPI_CTRL_STATUS_LPIATE;
		}

static void dwmac4_reset_eee_mode(struct mac_device_info *hw)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;
		if (en_tx_lpi_clockgating)
			value |= LPI_CTRL_STATUS_LPITCSE;
	}

	value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
	value &= ~(GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA);
	mask = LPI_CTRL_STATUS_LPIATE | LPI_CTRL_STATUS_LPIEN |
	       LPI_CTRL_STATUS_LPITXA | LPI_CTRL_STATUS_LPITCSE;

	value |= readl(ioaddr + GMAC4_LPI_CTRL_STATUS) & ~mask;
	writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);

	return 0;
}

static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link)
@@ -413,34 +426,13 @@ static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link)
	value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);

	if (link)
		value |= GMAC4_LPI_CTRL_STATUS_PLS;
		value |= LPI_CTRL_STATUS_PLS;
	else
		value &= ~GMAC4_LPI_CTRL_STATUS_PLS;
		value &= ~LPI_CTRL_STATUS_PLS;

	writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
}

static void dwmac4_set_eee_lpi_entry_timer(struct mac_device_info *hw, u32 et)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value = et & STMMAC_ET_MAX;
	int regval;

	/* Program LPI entry timer value into register */
	writel(value, ioaddr + GMAC4_LPI_ENTRY_TIMER);

	/* Enable/disable LPI entry timer */
	regval = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
	regval |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA;

	if (et)
		regval |= GMAC4_LPI_CTRL_STATUS_LPIATE;
	else
		regval &= ~GMAC4_LPI_CTRL_STATUS_LPIATE;

	writel(regval, ioaddr + GMAC4_LPI_CTRL_STATUS);
}

static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
{
	void __iomem *ioaddr = hw->pcsr;
@@ -849,17 +841,17 @@ static int dwmac4_irq_status(struct mac_device_info *hw,
		/* Clear LPI interrupt by reading MAC_LPI_Control_Status */
		u32 status = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);

		if (status & GMAC4_LPI_CTRL_STATUS_TLPIEN) {
		if (status & LPI_CTRL_STATUS_TLPIEN) {
			ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE;
			x->irq_tx_path_in_lpi_mode_n++;
		}
		if (status & GMAC4_LPI_CTRL_STATUS_TLPIEX) {
		if (status & LPI_CTRL_STATUS_TLPIEX) {
			ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE;
			x->irq_tx_path_exit_lpi_mode_n++;
		}
		if (status & GMAC4_LPI_CTRL_STATUS_RLPIEN)
		if (status & LPI_CTRL_STATUS_RLPIEN)
			x->irq_rx_path_in_lpi_mode_n++;
		if (status & GMAC4_LPI_CTRL_STATUS_RLPIEX)
		if (status & LPI_CTRL_STATUS_RLPIEX)
			x->irq_rx_path_exit_lpi_mode_n++;
	}

@@ -1201,9 +1193,7 @@ const struct stmmac_ops dwmac4_ops = {
	.pmt = dwmac4_pmt,
	.set_umac_addr = dwmac4_set_umac_addr,
	.get_umac_addr = dwmac4_get_umac_addr,
	.set_eee_mode = dwmac4_set_eee_mode,
	.reset_eee_mode = dwmac4_reset_eee_mode,
	.set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer,
	.set_lpi_mode = dwmac4_set_lpi_mode,
	.set_eee_timer = dwmac4_set_eee_timer,
	.set_eee_pls = dwmac4_set_eee_pls,
	.pcs_ctrl_ane = dwmac4_ctrl_ane,
@@ -1245,9 +1235,7 @@ const struct stmmac_ops dwmac410_ops = {
	.pmt = dwmac4_pmt,
	.set_umac_addr = dwmac4_set_umac_addr,
	.get_umac_addr = dwmac4_get_umac_addr,
	.set_eee_mode = dwmac4_set_eee_mode,
	.reset_eee_mode = dwmac4_reset_eee_mode,
	.set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer,
	.set_lpi_mode = dwmac4_set_lpi_mode,
	.set_eee_timer = dwmac4_set_eee_timer,
	.set_eee_pls = dwmac4_set_eee_pls,
	.pcs_ctrl_ane = dwmac4_ctrl_ane,
@@ -1291,9 +1279,7 @@ const struct stmmac_ops dwmac510_ops = {
	.pmt = dwmac4_pmt,
	.set_umac_addr = dwmac4_set_umac_addr,
	.get_umac_addr = dwmac4_get_umac_addr,
	.set_eee_mode = dwmac4_set_eee_mode,
	.reset_eee_mode = dwmac4_reset_eee_mode,
	.set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer,
	.set_lpi_mode = dwmac4_set_lpi_mode,
	.set_eee_timer = dwmac4_set_eee_timer,
	.set_eee_pls = dwmac4_set_eee_pls,
	.pcs_ctrl_ane = dwmac4_ctrl_ane,
Loading