Inter-revision diff: patch 12

Comparing v7 (message) to v2 (message)

--- v7
+++ v2
@@ -1,120 +1,209 @@
 From: Stefan Chulski <stefanc@marvell.com>
 
-Feature double size of BPPI by decreasing number of pools from 16 to 8.
-Increasing of BPPI size protect BM drop from BPPI underrun.
-Underrun could occurred due to stress on DDR and as result slow buffer
-transition from BPPE to BPPI.
-New BPPI threshold recommended by spec is:
-BPPI low threshold - 640 buffers
-BPPI high threshold - 832 buffers
-Supported only in PPv23.
+This patch add RXQ flow control configurations.
+Patch do not enable flow control itself, flow control
+disabled by default.
 
 Signed-off-by: Stefan Chulski <stefanc@marvell.com>
 ---
- drivers/net/ethernet/marvell/mvpp2/mvpp2.h      |  8 +++++
- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 35 +++++++++++++++++++-
- 2 files changed, 42 insertions(+), 1 deletion(-)
+ drivers/net/ethernet/marvell/mvpp2/mvpp2.h      |  40 ++++++-
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 111 ++++++++++++++++++++
+ 2 files changed, 147 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
-index 9071ab6..1967493 100644
+index 4c8e422..ba57465 100644
 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
 +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
-@@ -324,6 +324,10 @@
- #define     MVPP2_BM_HIGH_THRESH_MASK		0x7f0000
- #define     MVPP2_BM_HIGH_THRESH_VALUE(val)	((val) << \
- 						MVPP2_BM_HIGH_THRESH_OFFS)
-+#define     MVPP2_BM_BPPI_HIGH_THRESH		0x1E
-+#define     MVPP2_BM_BPPI_LOW_THRESH		0x1C
-+#define     MVPP23_BM_BPPI_HIGH_THRESH		0x34
-+#define     MVPP23_BM_BPPI_LOW_THRESH		0x28
- #define MVPP2_BM_INTR_CAUSE_REG(pool)		(0x6240 + ((pool) * 4))
- #define     MVPP2_BM_RELEASED_DELAY_MASK	BIT(0)
- #define     MVPP2_BM_ALLOC_FAILED_MASK		BIT(1)
-@@ -352,6 +356,10 @@
- #define MVPP2_OVERRUN_ETH_DROP			0x7000
- #define MVPP2_CLS_ETH_DROP			0x7020
- 
-+#define MVPP22_BM_POOL_BASE_ADDR_HIGH_REG	0x6310
-+#define     MVPP22_BM_POOL_BASE_ADDR_HIGH_MASK	0xff
-+#define     MVPP23_BM_8POOL_MODE		BIT(8)
-+
- /* Hit counters registers */
- #define MVPP2_CTRS_IDX				0x7040
- #define     MVPP22_CTRS_TX_CTR(port, txq)	((txq) | ((port) << 3) | BIT(7))
+@@ -763,10 +763,39 @@
+ 		((kb) * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
+ 
+ /* MSS Flow control */
+-#define MSS_SRAM_SIZE		0x800
+-#define FC_QUANTA		0xFFFF
+-#define FC_CLK_DIVIDER		0x140
+-#define MSS_THRESHOLD_STOP    768
++#define MSS_SRAM_SIZE			0x800
++#define MSS_FC_COM_REG			0
++#define FLOW_CONTROL_ENABLE_BIT		BIT(0)
++#define FLOW_CONTROL_UPDATE_COMMAND_BIT	BIT(31)
++#define FC_QUANTA			0xFFFF
++#define FC_CLK_DIVIDER			0x140
++
++#define MSS_RXQ_TRESH_BASE		0x200
++#define MSS_RXQ_TRESH_OFFS		4
++#define MSS_RXQ_TRESH_REG(q, fq)	(MSS_RXQ_TRESH_BASE + (((q) + (fq)) \
++					* MSS_RXQ_TRESH_OFFS))
++
++#define MSS_RXQ_TRESH_START_MASK	0xFFFF
++#define MSS_RXQ_TRESH_STOP_MASK		(0xFFFF << MSS_RXQ_TRESH_STOP_OFFS)
++#define MSS_RXQ_TRESH_STOP_OFFS		16
++
++#define MSS_RXQ_ASS_BASE	0x80
++#define MSS_RXQ_ASS_OFFS	4
++#define MSS_RXQ_ASS_PER_REG	4
++#define MSS_RXQ_ASS_PER_OFFS	8
++#define MSS_RXQ_ASS_PORTID_OFFS	0
++#define MSS_RXQ_ASS_PORTID_MASK	0x3
++#define MSS_RXQ_ASS_HOSTID_OFFS	2
++#define MSS_RXQ_ASS_HOSTID_MASK	0x3F
++
++#define MSS_RXQ_ASS_Q_BASE(q, fq) ((((q) + (fq)) % MSS_RXQ_ASS_PER_REG)	 \
++				  * MSS_RXQ_ASS_PER_OFFS)
++#define MSS_RXQ_ASS_PQ_BASE(q, fq) ((((q) + (fq)) / MSS_RXQ_ASS_PER_REG) \
++				   * MSS_RXQ_ASS_OFFS)
++#define MSS_RXQ_ASS_REG(q, fq) (MSS_RXQ_ASS_BASE + MSS_RXQ_ASS_PQ_BASE(q, fq))
++
++#define MSS_THRESHOLD_STOP	768
++#define MSS_THRESHOLD_START	1024
+ 
+ /* RX buffer constants */
+ #define MVPP2_SKB_SHINFO_SIZE \
+@@ -1191,6 +1220,9 @@ struct mvpp2_port {
+ 	bool rx_hwtstamp;
+ 	enum hwtstamp_tx_types tx_hwtstamp_type;
+ 	struct mvpp2_hwtstamp_queue tx_hwtstamp_queue[2];
++
++	/* Firmware TX flow control */
++	bool tx_fc;
+ };
+ 
+ /* The mvpp2_tx_desc and mvpp2_rx_desc structures describe the
 diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-index bbefc7e..f153060 100644
+index d79c687..2407c52 100644
 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -70,6 +70,11 @@ enum mvpp2_bm_pool_log_num {
- module_param(queue_mode, int, 0444);
- MODULE_PARM_DESC(queue_mode, "Set queue_mode (single=0, multi=1)");
- 
-+static int bm_underrun_protect = 1;
-+
-+module_param(bm_underrun_protect, int, 0444);
-+MODULE_PARM_DESC(bm_underrun_protect, "Set BM underrun protect feature (0-1), def=1");
-+
- /* Utility/helper methods */
- 
- void mvpp2_write(struct mvpp2 *priv, u32 offset, u32 data)
-@@ -424,6 +429,21 @@ static int mvpp2_bm_pool_create(struct device *dev, struct mvpp2 *priv,
- 
- 	val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id));
- 	val |= MVPP2_BM_START_MASK;
-+
-+	val &= ~MVPP2_BM_LOW_THRESH_MASK;
-+	val &= ~MVPP2_BM_HIGH_THRESH_MASK;
-+
-+	/* Set 8 Pools BPPI threshold if BM underrun protection feature
-+	 * were enabled
+@@ -744,6 +744,110 @@ static void *mvpp2_buf_alloc(struct mvpp2_port *port,
+ 	return data;
+ }
+ 
++/* Routine enable flow control for RXQs condition */
++static void mvpp2_rxq_enable_fc(struct mvpp2_port *port)
++{
++	int val, cm3_state, host_id, q;
++	int fq = port->first_rxq;
++	unsigned long flags;
++
++	spin_lock_irqsave(&port->priv->mss_spinlock, flags);
++
++	/* Remove Flow control enable bit to prevent race between FW and Kernel
++	 * If Flow control were enabled, it would be re-enabled.
 +	 */
-+	if (priv->hw_version == MVPP23 && bm_underrun_protect) {
-+		val |= MVPP2_BM_LOW_THRESH_VALUE(MVPP23_BM_BPPI_LOW_THRESH);
-+		val |= MVPP2_BM_HIGH_THRESH_VALUE(MVPP23_BM_BPPI_HIGH_THRESH);
-+	} else {
-+		val |= MVPP2_BM_LOW_THRESH_VALUE(MVPP2_BM_BPPI_LOW_THRESH);
-+		val |= MVPP2_BM_HIGH_THRESH_VALUE(MVPP2_BM_BPPI_HIGH_THRESH);
++	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
++	cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
++	val &= ~FLOW_CONTROL_ENABLE_BIT;
++	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
++
++	/* Set same Flow control for all RXQs */
++	for (q = 0; q < port->nrxqs; q++) {
++		/* Set stop and start Flow control RXQ thresholds */
++		val = MSS_THRESHOLD_START;
++		val |= (MSS_THRESHOLD_STOP << MSS_RXQ_TRESH_STOP_OFFS);
++		mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);
++
++		val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));
++		/* Set RXQ port ID */
++		val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));
++		val |= (port->id << MSS_RXQ_ASS_Q_BASE(q, fq));
++		val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
++			+ MSS_RXQ_ASS_HOSTID_OFFS));
++
++		/* Calculate RXQ host ID:
++		 * In Single queue mode: Host ID equal to Host ID used for
++		 *			 shared RX interrupt
++		 * In Multi queue mode: Host ID equal to number of
++		 *			RXQ ID / number of CoS queues
++		 * In Single resource mode: Host ID always equal to 0
++		 */
++		if (queue_mode == MVPP2_QDIST_SINGLE_MODE)
++			host_id = port->nqvecs;
++		else if (queue_mode == MVPP2_QDIST_MULTI_MODE)
++			host_id = q;
++		else
++			host_id = 0;
++
++		/* Set RXQ host ID */
++		val |= (host_id << (MSS_RXQ_ASS_Q_BASE(q, fq)
++			+ MSS_RXQ_ASS_HOSTID_OFFS));
++
++		mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
 +	}
 +
- 	mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);
- 
- 	bm_pool->size = size;
-@@ -592,6 +612,16 @@ static int mvpp2_bm_pools_init(struct device *dev, struct mvpp2 *priv)
- 	return err;
++	/* Notify Firmware that Flow control config space ready for update */
++	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
++	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
++	val |= cm3_state;
++	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
++
++	spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
++}
++
++/* Routine disable flow control for RXQs condition */
++static void mvpp2_rxq_disable_fc(struct mvpp2_port *port)
++{
++	int val, cm3_state, q;
++	unsigned long flags;
++	int fq = port->first_rxq;
++
++	spin_lock_irqsave(&port->priv->mss_spinlock, flags);
++
++	/* Remove Flow control enable bit to prevent race between FW and Kernel
++	 * If Flow control were enabled, it would be re-enabled.
++	 */
++	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
++	cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
++	val &= ~FLOW_CONTROL_ENABLE_BIT;
++	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
++
++	/* Disable Flow control for all RXQs */
++	for (q = 0; q < port->nrxqs; q++) {
++		/* Set threshold 0 to disable Flow control */
++		val = 0;
++		val |= (0 << MSS_RXQ_TRESH_STOP_OFFS);
++		mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);
++
++		val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));
++
++		val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));
++
++		val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
++			+ MSS_RXQ_ASS_HOSTID_OFFS));
++
++		mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
++	}
++
++	/* Notify Firmware that Flow control config space ready for update */
++	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
++	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
++	val |= cm3_state;
++	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
++
++	spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
++}
++
+ /* Release buffer to BM */
+ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
+ 				     dma_addr_t buf_dma_addr,
+@@ -3007,6 +3111,9 @@ static void mvpp2_cleanup_rxqs(struct mvpp2_port *port)
+ 
+ 	for (queue = 0; queue < port->nrxqs; queue++)
+ 		mvpp2_rxq_deinit(port, port->rxqs[queue]);
++
++	if (port->tx_fc)
++		mvpp2_rxq_disable_fc(port);
  }
  
-+/* Routine enable PPv23 8 pool mode */
-+static void mvpp23_bm_set_8pool_mode(struct mvpp2 *priv)
-+{
-+	int val;
-+
-+	val = mvpp2_read(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG);
-+	val |= MVPP23_BM_8POOL_MODE;
-+	mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val);
-+}
-+
- static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
- {
- 	enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
-@@ -645,6 +675,9 @@ static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
- 	if (!priv->bm_pools)
- 		return -ENOMEM;
- 
-+	if (priv->hw_version == MVPP23 && bm_underrun_protect)
-+		mvpp23_bm_set_8pool_mode(priv);
-+
- 	err = mvpp2_bm_pools_init(dev, priv);
- 	if (err < 0)
- 		return err;
-@@ -6491,7 +6524,7 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
- 			     val);
+ /* Init all Rx queues for port */
+@@ -3019,6 +3126,10 @@ static int mvpp2_setup_rxqs(struct mvpp2_port *port)
+ 		if (err)
+ 			goto err_cleanup;
  	}
- 
--	if (port->priv->global_tx_fc) {
-+	if (port->priv->global_tx_fc && bm_underrun_protect) {
- 		port->tx_fc = tx_pause;
- 		if (tx_pause)
- 			mvpp2_rxq_enable_fc(port);
++
++	if (port->tx_fc)
++		mvpp2_rxq_enable_fc(port);
++
+ 	return 0;
+ 
+ err_cleanup:
 -- 
 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