Thomas Bogendoerfer c01dfc
From: Huy Nguyen <huyn@mellanox.com>
Thomas Bogendoerfer c01dfc
Date: Fri, 6 Sep 2019 09:28:46 -0500
Thomas Bogendoerfer c01dfc
Subject: net/mlx5e: Query global pause state before setting prio2buffer
Thomas Bogendoerfer c01dfc
Patch-mainline: v5.5-rc1
Thomas Bogendoerfer c01dfc
Git-commit: 73e6551699a32fac703ceea09214d6580edcf2d5
Thomas Bogendoerfer c01dfc
References: bsc#1103990 FATE#326006
Thomas Bogendoerfer c01dfc
Thomas Bogendoerfer c01dfc
When the user changes prio2buffer mapping while global pause is
Thomas Bogendoerfer c01dfc
enabled, mlx5 driver incorrectly sets all active buffers
Thomas Bogendoerfer c01dfc
(buffer that has at least one priority mapped) to lossy.
Thomas Bogendoerfer c01dfc
Thomas Bogendoerfer c01dfc
Solution:
Thomas Bogendoerfer c01dfc
If global pause is enabled, set all the active buffers to lossless
Thomas Bogendoerfer c01dfc
in prio2buffer command.
Thomas Bogendoerfer c01dfc
Also, add error message when buffer size is not enough to meet
Thomas Bogendoerfer c01dfc
xoff threshold.
Thomas Bogendoerfer c01dfc
Thomas Bogendoerfer c01dfc
Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
Thomas Bogendoerfer c01dfc
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Thomas Bogendoerfer c01dfc
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Thomas Bogendoerfer c01dfc
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Thomas Bogendoerfer c01dfc
---
Thomas Bogendoerfer c01dfc
 drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c |   27 +++++++++++++--
Thomas Bogendoerfer c01dfc
 1 file changed, 25 insertions(+), 2 deletions(-)
Thomas Bogendoerfer c01dfc
Thomas Bogendoerfer c01dfc
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
Thomas Bogendoerfer c01dfc
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
Thomas Bogendoerfer c01dfc
@@ -155,8 +155,11 @@ static int update_xoff_threshold(struct
Thomas Bogendoerfer c01dfc
 		}
Thomas Bogendoerfer c01dfc
 
Thomas Bogendoerfer c01dfc
 		if (port_buffer->buffer[i].size <
Thomas Bogendoerfer c01dfc
-		    (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
Thomas Bogendoerfer c01dfc
+		    (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
Thomas Bogendoerfer c01dfc
+			pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
Thomas Bogendoerfer c01dfc
+			       i, port_buffer->buffer[i].size);
Thomas Bogendoerfer c01dfc
 			return -ENOMEM;
Thomas Bogendoerfer c01dfc
+		}
Thomas Bogendoerfer c01dfc
 
Thomas Bogendoerfer c01dfc
 		port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff;
Thomas Bogendoerfer c01dfc
 		port_buffer->buffer[i].xon  =
Thomas Bogendoerfer c01dfc
@@ -232,6 +235,26 @@ static int update_buffer_lossy(unsigned
Thomas Bogendoerfer c01dfc
 	return 0;
Thomas Bogendoerfer c01dfc
 }
Thomas Bogendoerfer c01dfc
 
Thomas Bogendoerfer c01dfc
+static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en)
Thomas Bogendoerfer c01dfc
+{
Thomas Bogendoerfer c01dfc
+	u32 g_rx_pause, g_tx_pause;
Thomas Bogendoerfer c01dfc
+	int err;
Thomas Bogendoerfer c01dfc
+
Thomas Bogendoerfer c01dfc
+	err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause);
Thomas Bogendoerfer c01dfc
+	if (err)
Thomas Bogendoerfer c01dfc
+		return err;
Thomas Bogendoerfer c01dfc
+
Thomas Bogendoerfer c01dfc
+	/* If global pause enabled, set all active buffers to lossless.
Thomas Bogendoerfer c01dfc
+	 * Otherwise, check PFC setting.
Thomas Bogendoerfer c01dfc
+	 */
Thomas Bogendoerfer c01dfc
+	if (g_rx_pause || g_tx_pause)
Thomas Bogendoerfer c01dfc
+		*pfc_en = 0xff;
Thomas Bogendoerfer c01dfc
+	else
Thomas Bogendoerfer c01dfc
+		err = mlx5_query_port_pfc(mdev, pfc_en, NULL);
Thomas Bogendoerfer c01dfc
+
Thomas Bogendoerfer c01dfc
+	return err;
Thomas Bogendoerfer c01dfc
+}
Thomas Bogendoerfer c01dfc
+
Thomas Bogendoerfer c01dfc
 #define MINIMUM_MAX_MTU 9216
Thomas Bogendoerfer c01dfc
 int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
Thomas Bogendoerfer c01dfc
 				    u32 change, unsigned int mtu,
Thomas Bogendoerfer c01dfc
@@ -277,7 +300,7 @@ int mlx5e_port_manual_buffer_config(stru
Thomas Bogendoerfer c01dfc
 
Thomas Bogendoerfer c01dfc
 	if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
Thomas Bogendoerfer c01dfc
 		update_prio2buffer = true;
Thomas Bogendoerfer c01dfc
-		err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL);
Thomas Bogendoerfer c01dfc
+		err = fill_pfc_en(priv->mdev, &curr_pfc_en);
Thomas Bogendoerfer c01dfc
 		if (err)
Thomas Bogendoerfer c01dfc
 			return err;
Thomas Bogendoerfer c01dfc