svn commit: r330608 - in head/sys/dev/mlx5: . mlx5_core mlx5_en

Hans Petter Selasky hselasky at FreeBSD.org
Wed Mar 7 15:23:09 UTC 2018


Author: hselasky
Date: Wed Mar  7 15:23:07 2018
New Revision: 330608
URL: https://svnweb.freebsd.org/changeset/base/330608

Log:
  Implement priority to traffic class mapping in mlx5core.
  
  Add support for mapping priority to traffic class via sysctl
  
  Submitted by:	Slava Shwartsman <slavash at mellanox.com>
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/dev/mlx5/mlx5_core/mlx5_port.c
  head/sys/dev/mlx5/mlx5_en/en.h
  head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
  head/sys/dev/mlx5/port.h

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_port.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_port.c	Wed Mar  7 15:17:36 2018	(r330607)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_port.c	Wed Mar  7 15:23:07 2018	(r330608)
@@ -943,6 +943,48 @@ int mlx5_modify_port_tc_rate_limit(struct mlx5_core_de
 }
 EXPORT_SYMBOL_GPL(mlx5_modify_port_tc_rate_limit);
 
+int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
+			    u8 prio, u8 *tc)
+{
+	u32 in[MLX5_ST_SZ_DW(qtct_reg)];
+	u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+	int err;
+
+	memset(in, 0, sizeof(in));
+	memset(out, 0, sizeof(out));
+
+	MLX5_SET(qtct_reg, in, port_number, 1);
+	MLX5_SET(qtct_reg, in, prio, prio);
+
+	err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
+				   sizeof(out), MLX5_REG_QTCT, 0, 0);
+	if (!err)
+		*tc = MLX5_GET(qtct_reg, out, tclass);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_prio_tc);
+
+int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, int prio_index,
+			  const u8 prio_tc)
+{
+	u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {};
+	u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+	int err;
+
+	if (prio_tc > mlx5_max_tc(mdev))
+		return -EINVAL;
+
+	MLX5_SET(qtct_reg, in, prio, prio_index);
+	MLX5_SET(qtct_reg, in, tclass, prio_tc);
+
+	err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
+				   sizeof(out), MLX5_REG_QTCT, 0, 1);
+
+	return (err);
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
+
 int mlx5_modify_port_cong_params(struct mlx5_core_dev *mdev,
 				 void *in, int in_size)
 {

Modified: head/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/en.h	Wed Mar  7 15:17:36 2018	(r330607)
+++ head/sys/dev/mlx5/mlx5_en/en.h	Wed Mar  7 15:23:07 2018	(r330608)
@@ -429,6 +429,7 @@ struct mlx5e_params_ethtool {
 	u64	arg [0];
 	MLX5E_PARAMS(MLX5E_STATS_VAR)
 	u64	max_bw_value[IEEE_8021QAZ_MAX_TCS];
+	u8	prio_tc[IEEE_8021QAZ_MAX_TCS];
 };
 
 /* EEPROM Standards for plug in modules */

Modified: head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c	Wed Mar  7 15:17:36 2018	(r330607)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c	Wed Mar  7 15:23:07 2018	(r330608)
@@ -175,6 +175,60 @@ done:
 	return (err);
 }
 
+static int
+mlx5e_get_prio_tc(struct mlx5e_priv *priv)
+{
+	struct mlx5_core_dev *mdev = priv->mdev;
+	int err = 0;
+	int i;
+
+	PRIV_LOCK(priv);
+	if (!MLX5_CAP_GEN(priv->mdev, ets)) {
+		PRIV_UNLOCK(priv);
+		return (EOPNOTSUPP);
+	}
+
+	for (i = 0; i <= mlx5_max_tc(priv->mdev); i++) {
+		err = -mlx5_query_port_prio_tc(mdev, i, &(priv->params_ethtool.prio_tc[i]));
+		if (err)
+			break;
+	}
+
+	PRIV_UNLOCK(priv);
+	return (err);
+}
+
+static int
+mlx5e_prio_to_tc_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct mlx5e_priv *priv = arg1;
+	int prio_index = arg2;
+	struct mlx5_core_dev *mdev = priv->mdev;
+	int err;
+	uint8_t result = priv->params_ethtool.prio_tc[prio_index];
+
+	PRIV_LOCK(priv);
+	err = sysctl_handle_8(oidp, &result, 0, req);
+	if (err || !req->newptr ||
+	    result == priv->params_ethtool.prio_tc[prio_index])
+		goto done;
+
+	if (result > mlx5_max_tc(mdev)) {
+		err = ERANGE;
+		goto done;
+	}
+
+	err = -mlx5_set_port_prio_tc(mdev, prio_index, result);
+	if (err)
+		goto done;
+
+	priv->params_ethtool.prio_tc[prio_index] = result;
+
+done:
+	PRIV_UNLOCK(priv);
+	return (err);
+}
+
 #define	MLX5_PARAM_OFFSET(n)				\
     __offsetof(struct mlx5e_priv, params_ethtool.n)
 
@@ -943,5 +997,17 @@ mlx5e_create_ethtool(struct mlx5e_priv *priv)
 				priv, i, mlx5e_tc_maxrate_handler, "QU",
 				"Max rate for priority, specified in kilobits, where kilo=1000, \
 				max_rate must be divisible by 100000");
+	}
+
+	if (mlx5e_get_prio_tc(priv))
+		return;
+
+	for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+		char name[32];
+		snprintf(name, sizeof(name), "prio_%d_to_tc", i);
+		SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(qos_node),
+				OID_AUTO, name, CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_MPSAFE,
+				priv, i, mlx5e_prio_to_tc_handler, "CU",
+				"Set priority to traffic class");
 	}
 }

Modified: head/sys/dev/mlx5/port.h
==============================================================================
--- head/sys/dev/mlx5/port.h	Wed Mar  7 15:17:36 2018	(r330607)
+++ head/sys/dev/mlx5/port.h	Wed Mar  7 15:23:07 2018	(r330608)
@@ -151,4 +151,8 @@ int mlx5_query_port_tc_rate_limit(struct mlx5_core_dev
 int mlx5_modify_port_tc_rate_limit(struct mlx5_core_dev *mdev,
 				   const u8 *max_bw_value,
 				   const u8 *max_bw_units);
+int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
+			    u8 prio, u8 *tc);
+int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, int prio_index,
+			  const u8 prio_tc);
 #endif /* __MLX5_PORT_H__ */


More information about the svn-src-head mailing list