Commit ca68d563 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-fixes-2020-07-02' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5 fixes 2020-07-02

This series introduces some fixes to mlx5 driver.

V1->v2:
 - Drop "ip -s" patch and mirred device hold reference patch.
 - Will revise them in a later submission.

Please pull and let me know if there is any problem.

For -stable v5.2
 ('net/mlx5: Fix eeprom support for SFP module')

For -stable v5.4
 ('net/mlx5e: Fix 50G per lane indication')

For -stable v5.5
 ('net/mlx5e: Fix CPU mapping after function reload to avoid aRFS RX crash')
 ('net/mlx5e: Fix VXLAN configuration restore after function reload')

For -stable v5.7
 ('net/mlx5e: CT: Fix memory leak in cleanup')
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 14b032b8 eb32b3f5
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ struct mlx5e_dcbx {
	bool                       manual_buffer;
	bool                       manual_buffer;
	u32                        cable_len;
	u32                        cable_len;
	u32                        xoff;
	u32                        xoff;
	u16                        port_buff_cell_sz;
};
};


#define MLX5E_MAX_DSCP (64)
#define MLX5E_MAX_DSCP (64)
+18 −3
Original line number Original line Diff line number Diff line
@@ -78,11 +78,26 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = {
	[MLX5E_400GAUI_8]			= 400000,
	[MLX5E_400GAUI_8]			= 400000,
};
};


bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev)
{
	struct mlx5e_port_eth_proto eproto;
	int err;

	if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet))
		return true;

	err = mlx5_port_query_eth_proto(mdev, 1, true, &eproto);
	if (err)
		return false;

	return !!eproto.cap;
}

static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
				     const u32 **arr, u32 *size,
				     const u32 **arr, u32 *size,
				     bool force_legacy)
				     bool force_legacy)
{
{
	bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
	bool ext = force_legacy ? false : mlx5e_ptys_ext_supported(mdev);


	*size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
	*size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
		      ARRAY_SIZE(mlx5e_link_speed);
		      ARRAY_SIZE(mlx5e_link_speed);
@@ -177,7 +192,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
	bool ext;
	bool ext;
	int err;
	int err;


	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
	ext = mlx5e_ptys_ext_supported(mdev);
	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
	if (err)
	if (err)
		goto out;
		goto out;
@@ -205,7 +220,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
	int err;
	int err;
	int i;
	int i;


	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
	ext = mlx5e_ptys_ext_supported(mdev);
	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
	if (err)
	if (err)
		return err;
		return err;
+1 −1
Original line number Original line Diff line number Diff line
@@ -54,7 +54,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,
u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,
			       bool force_legacy);
			       bool force_legacy);

bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev);
int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);
int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);
int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
+29 −24
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@
int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
			    struct mlx5e_port_buffer *port_buffer)
			    struct mlx5e_port_buffer *port_buffer)
{
{
	u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5_core_dev *mdev = priv->mdev;
	int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
	int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
	u32 total_used = 0;
	u32 total_used = 0;
@@ -57,11 +58,11 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
		port_buffer->buffer[i].epsb =
		port_buffer->buffer[i].epsb =
			MLX5_GET(bufferx_reg, buffer, epsb);
			MLX5_GET(bufferx_reg, buffer, epsb);
		port_buffer->buffer[i].size =
		port_buffer->buffer[i].size =
			MLX5_GET(bufferx_reg, buffer, size) << MLX5E_BUFFER_CELL_SHIFT;
			MLX5_GET(bufferx_reg, buffer, size) * port_buff_cell_sz;
		port_buffer->buffer[i].xon =
		port_buffer->buffer[i].xon =
			MLX5_GET(bufferx_reg, buffer, xon_threshold) << MLX5E_BUFFER_CELL_SHIFT;
			MLX5_GET(bufferx_reg, buffer, xon_threshold) * port_buff_cell_sz;
		port_buffer->buffer[i].xoff =
		port_buffer->buffer[i].xoff =
			MLX5_GET(bufferx_reg, buffer, xoff_threshold) << MLX5E_BUFFER_CELL_SHIFT;
			MLX5_GET(bufferx_reg, buffer, xoff_threshold) * port_buff_cell_sz;
		total_used += port_buffer->buffer[i].size;
		total_used += port_buffer->buffer[i].size;


		mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i,
		mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i,
@@ -73,7 +74,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
	}
	}


	port_buffer->port_buffer_size =
	port_buffer->port_buffer_size =
		MLX5_GET(pbmc_reg, out, port_buffer_size) << MLX5E_BUFFER_CELL_SHIFT;
		MLX5_GET(pbmc_reg, out, port_buffer_size) * port_buff_cell_sz;
	port_buffer->spare_buffer_size =
	port_buffer->spare_buffer_size =
		port_buffer->port_buffer_size - total_used;
		port_buffer->port_buffer_size - total_used;


@@ -88,9 +89,9 @@ out:
static int port_set_buffer(struct mlx5e_priv *priv,
static int port_set_buffer(struct mlx5e_priv *priv,
			   struct mlx5e_port_buffer *port_buffer)
			   struct mlx5e_port_buffer *port_buffer)
{
{
	u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5_core_dev *mdev = priv->mdev;
	int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
	int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
	void *buffer;
	void *in;
	void *in;
	int err;
	int err;
	int i;
	int i;
@@ -104,16 +105,18 @@ static int port_set_buffer(struct mlx5e_priv *priv,
		goto out;
		goto out;


	for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
	for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
		buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
		void *buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);

		u64 size = port_buffer->buffer[i].size;
		MLX5_SET(bufferx_reg, buffer, size,
		u64 xoff = port_buffer->buffer[i].xoff;
			 port_buffer->buffer[i].size >> MLX5E_BUFFER_CELL_SHIFT);
		u64 xon = port_buffer->buffer[i].xon;
		MLX5_SET(bufferx_reg, buffer, lossy,

			 port_buffer->buffer[i].lossy);
		do_div(size, port_buff_cell_sz);
		MLX5_SET(bufferx_reg, buffer, xoff_threshold,
		do_div(xoff, port_buff_cell_sz);
			 port_buffer->buffer[i].xoff >> MLX5E_BUFFER_CELL_SHIFT);
		do_div(xon, port_buff_cell_sz);
		MLX5_SET(bufferx_reg, buffer, xon_threshold,
		MLX5_SET(bufferx_reg, buffer, size, size);
			 port_buffer->buffer[i].xon >> MLX5E_BUFFER_CELL_SHIFT);
		MLX5_SET(bufferx_reg, buffer, lossy, port_buffer->buffer[i].lossy);
		MLX5_SET(bufferx_reg, buffer, xoff_threshold, xoff);
		MLX5_SET(bufferx_reg, buffer, xon_threshold, xon);
	}
	}


	err = mlx5e_port_set_pbmc(mdev, in);
	err = mlx5e_port_set_pbmc(mdev, in);
@@ -143,7 +146,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
}
}


static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
				 u32 xoff, unsigned int max_mtu)
				 u32 xoff, unsigned int max_mtu, u16 port_buff_cell_sz)
{
{
	int i;
	int i;


@@ -155,7 +158,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
		}
		}


		if (port_buffer->buffer[i].size <
		if (port_buffer->buffer[i].size <
		    (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
		    (xoff + max_mtu + port_buff_cell_sz)) {
			pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
			pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
			       i, port_buffer->buffer[i].size);
			       i, port_buffer->buffer[i].size);
			return -ENOMEM;
			return -ENOMEM;
@@ -175,6 +178,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
 *	@pfc_en: <input> current pfc configuration
 *	@pfc_en: <input> current pfc configuration
 *	@buffer: <input> current prio to buffer mapping
 *	@buffer: <input> current prio to buffer mapping
 *	@xoff:   <input> xoff value
 *	@xoff:   <input> xoff value
 *	@port_buff_cell_sz: <input> port buffer cell_size
 *	@port_buffer: <output> port receive buffer configuration
 *	@port_buffer: <output> port receive buffer configuration
 *	@change: <output>
 *	@change: <output>
 *
 *
@@ -189,7 +193,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
 *	sets change to true if buffer configuration was modified.
 *	sets change to true if buffer configuration was modified.
 */
 */
static int update_buffer_lossy(unsigned int max_mtu,
static int update_buffer_lossy(unsigned int max_mtu,
			       u8 pfc_en, u8 *buffer, u32 xoff,
			       u8 pfc_en, u8 *buffer, u32 xoff, u16 port_buff_cell_sz,
			       struct mlx5e_port_buffer *port_buffer,
			       struct mlx5e_port_buffer *port_buffer,
			       bool *change)
			       bool *change)
{
{
@@ -225,7 +229,7 @@ static int update_buffer_lossy(unsigned int max_mtu,
	}
	}


	if (changed) {
	if (changed) {
		err = update_xoff_threshold(port_buffer, xoff, max_mtu);
		err = update_xoff_threshold(port_buffer, xoff, max_mtu, port_buff_cell_sz);
		if (err)
		if (err)
			return err;
			return err;


@@ -262,6 +266,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
				    u32 *buffer_size,
				    u32 *buffer_size,
				    u8 *prio2buffer)
				    u8 *prio2buffer)
{
{
	u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
	struct mlx5e_port_buffer port_buffer;
	struct mlx5e_port_buffer port_buffer;
	u32 xoff = calculate_xoff(priv, mtu);
	u32 xoff = calculate_xoff(priv, mtu);
	bool update_prio2buffer = false;
	bool update_prio2buffer = false;
@@ -282,7 +287,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,


	if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
	if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
		update_buffer = true;
		update_buffer = true;
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
		if (err)
		if (err)
			return err;
			return err;
	}
	}
@@ -292,7 +297,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
		if (err)
		if (err)
			return err;
			return err;


		err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff,
		err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff, port_buff_cell_sz,
					  &port_buffer, &update_buffer);
					  &port_buffer, &update_buffer);
		if (err)
		if (err)
			return err;
			return err;
@@ -304,7 +309,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
		if (err)
		if (err)
			return err;
			return err;


		err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer,
		err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, port_buff_cell_sz,
					  xoff, &port_buffer, &update_buffer);
					  xoff, &port_buffer, &update_buffer);
		if (err)
		if (err)
			return err;
			return err;
@@ -329,7 +334,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
			return -EINVAL;
			return -EINVAL;


		update_buffer = true;
		update_buffer = true;
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
		if (err)
		if (err)
			return err;
			return err;
	}
	}
@@ -337,7 +342,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
	/* Need to update buffer configuration if xoff value is changed */
	/* Need to update buffer configuration if xoff value is changed */
	if (!update_buffer && xoff != priv->dcbx.xoff) {
	if (!update_buffer && xoff != priv->dcbx.xoff) {
		update_buffer = true;
		update_buffer = true;
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
		err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
		if (err)
		if (err)
			return err;
			return err;
	}
	}
+0 −1
Original line number Original line Diff line number Diff line
@@ -36,7 +36,6 @@
#include "port.h"
#include "port.h"


#define MLX5E_MAX_BUFFER 8
#define MLX5E_MAX_BUFFER 8
#define MLX5E_BUFFER_CELL_SHIFT 7
#define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */
#define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */


#define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \
#define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \
Loading