Commit 2788d841 authored by Stefan Chulski's avatar Stefan Chulski Committed by David S. Miller
Browse files

net: mvpp2: add FCA periodic timer configurations



Flow Control periodic timer would be used if port in
XOFF to transmit periodic XOFF frames.

Signed-off-by: default avatarStefan Chulski <stefanc@marvell.com>
Acked-by: default avatarMarcin Wojtas <mw@semihalf.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d07ea73f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -596,6 +596,15 @@
#define     MVPP22_MPCS_CLK_RESET_DIV_RATIO(n)	((n) << 4)
#define     MVPP22_MPCS_CLK_RESET_DIV_SET	BIT(11)

/* FCA registers. PPv2.2 and PPv2.3 */
#define MVPP22_FCA_BASE(port)			(0x7600 + (port) * 0x1000)
#define MVPP22_FCA_REG_SIZE			16
#define MVPP22_FCA_REG_MASK			0xFFFF
#define MVPP22_FCA_CONTROL_REG			0x0
#define MVPP22_FCA_ENABLE_PERIODIC		BIT(11)
#define MVPP22_PERIODIC_COUNTER_LSB_REG		(0x110)
#define MVPP22_PERIODIC_COUNTER_MSB_REG		(0x114)

/* XPCS registers. PPv2.2 and PPv2.3 */
#define MVPP22_XPCS_BASE(port)			(0x7400 + (port) * 0x1000)
#define MVPP22_XPCS_CFG0			0x0
@@ -751,6 +760,10 @@
#define MVPP2_TX_FIFO_THRESHOLD(kb)	\
		((kb) * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)

/* MSS Flow control */
#define FC_QUANTA		0xFFFF
#define FC_CLK_DIVIDER		100

/* RX buffer constants */
#define MVPP2_SKB_SHINFO_SIZE \
	SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
+45 −0
Original line number Diff line number Diff line
@@ -1280,6 +1280,49 @@ static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
}

static void mvpp22_gop_fca_enable_periodic(struct mvpp2_port *port, bool en)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *fca = priv->iface_base + MVPP22_FCA_BASE(port->gop_id);
	u32 val;

	val = readl(fca + MVPP22_FCA_CONTROL_REG);
	val &= ~MVPP22_FCA_ENABLE_PERIODIC;
	if (en)
		val |= MVPP22_FCA_ENABLE_PERIODIC;
	writel(val, fca + MVPP22_FCA_CONTROL_REG);
}

static void mvpp22_gop_fca_set_timer(struct mvpp2_port *port, u32 timer)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *fca = priv->iface_base + MVPP22_FCA_BASE(port->gop_id);
	u32 lsb, msb;

	lsb = timer & MVPP22_FCA_REG_MASK;
	msb = timer >> MVPP22_FCA_REG_SIZE;

	writel(lsb, fca + MVPP22_PERIODIC_COUNTER_LSB_REG);
	writel(msb, fca + MVPP22_PERIODIC_COUNTER_MSB_REG);
}

/* Set Flow Control timer x100 faster than pause quanta to ensure that link
 * partner won't send traffic if port is in XOFF mode.
 */
static void mvpp22_gop_fca_set_periodic_timer(struct mvpp2_port *port)
{
	u32 timer;

	timer = (port->priv->tclk / (USEC_PER_SEC * FC_CLK_DIVIDER))
		* FC_QUANTA;

	mvpp22_gop_fca_enable_periodic(port, false);

	mvpp22_gop_fca_set_timer(port, timer);

	mvpp22_gop_fca_enable_periodic(port, true);
}

static int mvpp22_gop_init(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
@@ -1324,6 +1367,8 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
	val |= GENCONF_SOFT_RESET1_GOP;
	regmap_write(priv->sysctrl_base, GENCONF_SOFT_RESET1, val);

	mvpp22_gop_fca_set_periodic_timer(port);

unsupported_conf:
	return 0;