Inter-revision diff: patch 8

Comparing v9 (message) to v2 (message)

--- v9
+++ v2
@@ -1,135 +1,107 @@
 From: Stefan Chulski <stefanc@marvell.com>
 
-The firmware needs to monitor the RX Non-occupied descriptor
-bits for flow control to move to XOFF mode.
-These bits need to be unmasked to be functional, but they will
-not raise interrupts as we leave the RX exception summary
-bit in MVPP2_ISR_RX_TX_MASK_REG clear.
+Flow Control periodic timer would be used if port in
+XOFF to transmit periodic XOFF frames.
 
 Signed-off-by: Stefan Chulski <stefanc@marvell.com>
 ---
- drivers/net/ethernet/marvell/mvpp2/mvpp2.h      |  3 ++
- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 44 ++++++++++++++++----
- 2 files changed, 40 insertions(+), 7 deletions(-)
+ drivers/net/ethernet/marvell/mvpp2/mvpp2.h      | 13 +++++-
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 45 ++++++++++++++++++++
+ 2 files changed, 57 insertions(+), 1 deletion(-)
 
 diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
-index 9239d80..d2cc513c 100644
+index cac9885..0861c0b 100644
 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
 +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
-@@ -295,6 +295,8 @@
- #define     MVPP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK	0x3fc00000
- #define     MVPP2_PON_CAUSE_MISC_SUM_MASK		BIT(31)
- #define MVPP2_ISR_MISC_CAUSE_REG		0x55b0
-+#define MVPP2_ISR_RX_ERR_CAUSE_REG(port)	(0x5520 + 4 * (port))
-+#define     MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK	0x00ff
+@@ -596,6 +596,15 @@
+ #define     MVPP22_MPCS_CLK_RESET_DIV_RATIO(n)	((n) << 4)
+ #define     MVPP22_MPCS_CLK_RESET_DIV_SET	BIT(11)
  
- /* Buffer Manager registers */
- #define MVPP2_BM_POOL_BASE_REG(pool)		(0x6000 + ((pool) * 4))
-@@ -763,6 +765,7 @@
++/* 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
+@@ -752,7 +761,9 @@
+ 		((kb) * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
+ 
  /* MSS Flow control */
- #define FC_QUANTA		0xFFFF
- #define FC_CLK_DIVIDER		100
-+#define MSS_THRESHOLD_STOP	768
+-#define MSS_SRAM_SIZE	0x800
++#define MSS_SRAM_SIZE		0x800
++#define FC_QUANTA		0xFFFF
++#define FC_CLK_DIVIDER		0x140
  
  /* RX buffer constants */
  #define MVPP2_SKB_SHINFO_SIZE \
 diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-index 761f745..8b4073c 100644
+index 7143909..9d69752 100644
 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -1133,14 +1133,19 @@ static inline void mvpp2_qvec_interrupt_disable(struct mvpp2_queue_vector *qvec)
- static void mvpp2_interrupts_mask(void *arg)
- {
- 	struct mvpp2_port *port = arg;
-+	int cpu = smp_processor_id();
-+	u32 thread;
- 
- 	/* If the thread isn't used, don't do anything */
--	if (smp_processor_id() > port->priv->nthreads)
-+	if (cpu > port->priv->nthreads)
- 		return;
- 
--	mvpp2_thread_write(port->priv,
--			   mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
-+	thread = mvpp2_cpu_to_thread(port->priv, cpu);
-+
-+	mvpp2_thread_write(port->priv, thread,
- 			   MVPP2_ISR_RX_TX_MASK_REG(port->id), 0);
-+	mvpp2_thread_write(port->priv, thread,
-+			   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id), 0);
+@@ -1293,6 +1293,49 @@ static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
+ 	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
  }
  
- /* Unmask the current thread's Rx/Tx interrupts.
-@@ -1150,20 +1155,25 @@ static void mvpp2_interrupts_mask(void *arg)
- static void mvpp2_interrupts_unmask(void *arg)
- {
- 	struct mvpp2_port *port = arg;
--	u32 val;
-+	int cpu = smp_processor_id();
-+	u32 val, thread;
- 
- 	/* If the thread isn't used, don't do anything */
--	if (smp_processor_id() > port->priv->nthreads)
-+	if (cpu > port->priv->nthreads)
- 		return;
- 
-+	thread = mvpp2_cpu_to_thread(port->priv, cpu);
-+
- 	val = MVPP2_CAUSE_MISC_SUM_MASK |
- 		MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK(port->priv->hw_version);
- 	if (port->has_tx_irqs)
- 		val |= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
- 
--	mvpp2_thread_write(port->priv,
--			   mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
-+	mvpp2_thread_write(port->priv, thread,
- 			   MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
-+	mvpp2_thread_write(port->priv, thread,
-+			   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
-+			   MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
- }
- 
- static void
-@@ -1188,6 +1198,9 @@ static void mvpp2_interrupts_unmask(void *arg)
- 
- 		mvpp2_thread_write(port->priv, v->sw_thread_id,
- 				   MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
-+		mvpp2_thread_write(port->priv, v->sw_thread_id,
-+				   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
-+				   MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
- 	}
- }
- 
-@@ -2393,6 +2406,20 @@ static void mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)
- 	}
- }
- 
-+/* Set the number of non-occupied descriptors threshold */
-+static void mvpp2_set_rxq_free_tresh(struct mvpp2_port *port,
-+				     struct mvpp2_rx_queue *rxq)
++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;
 +
-+	mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
-+
-+	val = mvpp2_read(port->priv, MVPP2_RXQ_THRESH_REG);
-+	val &= ~MVPP2_RXQ_NON_OCCUPIED_MASK;
-+	val |= MSS_THRESHOLD_STOP << MVPP2_RXQ_NON_OCCUPIED_OFFSET;
-+	mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, 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);
 +}
 +
- /* Set the number of packets that will be received before Rx interrupt
-  * will be generated by HW.
-  */
-@@ -2648,6 +2675,9 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
- 	mvpp2_rx_pkts_coal_set(port, rxq);
- 	mvpp2_rx_time_coal_set(port, rxq);
++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 x140 faster than pause quanta to ensure that link
++ * partner won't send taffic if port 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;
+@@ -1337,6 +1380,8 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
+ 	val |= GENCONF_SOFT_RESET1_GOP;
+ 	regmap_write(priv->sysctrl_base, GENCONF_SOFT_RESET1, val);
  
-+	/* Set the number of non occupied descriptors threshold */
-+	mvpp2_set_rxq_free_tresh(port, rxq);
++	mvpp22_gop_fca_set_periodic_timer(port);
 +
- 	/* Add number of descriptors ready for receiving packets */
- 	mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);
+ unsupported_conf:
+ 	return 0;
  
 -- 
 1.9.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help