[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1510772411-17054-3-git-send-email-eranbe@mellanox.com>
Date: Wed, 15 Nov 2017 21:00:11 +0200
From: Eran Ben Elisha <eranbe@...lanox.com>
To: netdev@...r.kernel.org, "David S. Miller" <davem@...emloft.net>,
"John W. Linville" <linville@...driver.com>,
Saeed Mahameed <saeedm@...lanox.com>
Cc: Gal Pressman <galp@...lanox.com>,
Ariel Almog <ariela@...lanox.com>,
Eran Ben Elisha <eranbe@...lanox.com>,
Inbar Karmy <inbark@...lanox.com>
Subject: [RFC PATCH net-next 2/2] net/mlx5e: PFC stall prevention support
From: Inbar Karmy <inbark@...lanox.com>
Implement set/get functions to configure PFC stall prevention
mode by ethtool.
On default the stall prevention timeout is configured to 8 sec.
Auto mode will set the stall prevention timeout to be 100 msec.
Signed-off-by: Inbar Karmy <inbark@...lanox.com>
Reviewed-by: Eran Ben Elisha <eranbe@...lanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 51 ++++++++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/port.c | 56 ++++++++++++++++++----
include/linux/mlx5/mlx5_ifc.h | 22 +++++++--
include/linux/mlx5/port.h | 5 ++
4 files changed, 121 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 23425f0..74096f1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1180,6 +1180,55 @@ static int mlx5e_set_pauseparam(struct net_device *netdev,
return err;
}
+#define MLX5E_PFC_PREVEN_CRITICAL_AUTO_MSEC 100
+#define MLX5E_PFC_PREVEN_MINOR_AUTO_MSEC 85
+#define MLX5E_PFC_PREVEN_CRITICAL_DEFAULT_MSEC 8000
+#define MLX5E_PFC_PREVEN_MINOR_DEFAULT_MSEC 6800
+
+static int mlx5e_get_pfc_prevention_mode(struct net_device *netdev,
+ struct ethtool_pfc_prevention *pfc_preven)
+{
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5_core_dev *mdev = priv->mdev;
+ u16 pfc_prevention_critical;
+ int err;
+
+ if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask))
+ return -EOPNOTSUPP;
+
+ err = mlx5_query_port_pfc_prevention(mdev, &pfc_prevention_critical);
+
+ pfc_preven->mode = (pfc_prevention_critical ==
+ MLX5E_PFC_PREVEN_CRITICAL_DEFAULT_MSEC) ?
+ ETH_PFC_PREVENTION_DEFAULT : ETH_PFC_PREVENTION_AUTO;
+ return err;
+}
+
+static int mlx5e_set_pfc_prevention_mode(struct net_device *netdev,
+ struct ethtool_pfc_prevention *pfc_preven)
+{
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5_core_dev *mdev = priv->mdev;
+ u16 pfc_prevention_critical;
+ u16 pfc_prevention_minor;
+ int err;
+
+ if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask))
+ return -EOPNOTSUPP;
+
+ pfc_prevention_critical = (pfc_preven->mode == ETH_PFC_PREVENTION_DEFAULT) ?
+ MLX5E_PFC_PREVEN_CRITICAL_DEFAULT_MSEC :
+ MLX5E_PFC_PREVEN_CRITICAL_AUTO_MSEC;
+ pfc_prevention_minor = (pfc_prevention_critical ==
+ MLX5E_PFC_PREVEN_CRITICAL_DEFAULT_MSEC) ?
+ MLX5E_PFC_PREVEN_MINOR_DEFAULT_MSEC :
+ MLX5E_PFC_PREVEN_MINOR_AUTO_MSEC;
+ err = mlx5_set_port_pfc_prevention(mdev, pfc_prevention_critical,
+ pfc_prevention_minor);
+
+ return err;
+}
+
int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
struct ethtool_ts_info *info)
{
@@ -1696,6 +1745,8 @@ static int mlx5e_flash_device(struct net_device *dev,
.set_tunable = mlx5e_set_tunable,
.get_pauseparam = mlx5e_get_pauseparam,
.set_pauseparam = mlx5e_set_pauseparam,
+ .get_pfc_prevention_mode = mlx5e_get_pfc_prevention_mode,
+ .set_pfc_prevention_mode = mlx5e_set_pfc_prevention_mode,
.get_ts_info = mlx5e_get_ts_info,
.set_phys_id = mlx5e_set_phys_id,
.get_wol = mlx5e_get_wol,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index c37d00c..d2f7357 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -483,6 +483,16 @@ int mlx5_core_query_ib_ppcnt(struct mlx5_core_dev *dev,
}
EXPORT_SYMBOL_GPL(mlx5_core_query_ib_ppcnt);
+static int mlx5_query_pfcc_reg(struct mlx5_core_dev *dev, u32 *out, u32 out_size)
+{
+ u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
+
+ MLX5_SET(pfcc_reg, in, local_port, 1);
+
+ return mlx5_core_access_reg(dev, in, sizeof(in), out,
+ out_size, MLX5_REG_PFCC, 0, 0);
+}
+
int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause)
{
u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
@@ -500,13 +510,10 @@ int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause)
int mlx5_query_port_pause(struct mlx5_core_dev *dev,
u32 *rx_pause, u32 *tx_pause)
{
- u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
int err;
- MLX5_SET(pfcc_reg, in, local_port, 1);
- err = mlx5_core_access_reg(dev, in, sizeof(in), out,
- sizeof(out), MLX5_REG_PFCC, 0, 0);
+ err = mlx5_query_pfcc_reg(dev, out, sizeof(out));
if (err)
return err;
@@ -520,6 +527,42 @@ int mlx5_query_port_pause(struct mlx5_core_dev *dev,
}
EXPORT_SYMBOL_GPL(mlx5_query_port_pause);
+int mlx5_set_port_pfc_prevention(struct mlx5_core_dev *dev,
+ u16 pfc_preven_critical, u16 pfc_preven_minor)
+{
+ u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
+ u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
+
+ MLX5_SET(pfcc_reg, in, local_port, 1);
+ MLX5_SET(pfcc_reg, in, pptx_mask_n, 1);
+ MLX5_SET(pfcc_reg, in, pprx_mask_n, 1);
+ MLX5_SET(pfcc_reg, in, ppan_mask_n, 1);
+ MLX5_SET(pfcc_reg, in, critical_stall_mask, 1);
+ MLX5_SET(pfcc_reg, in, minor_stall_mask, 1);
+ MLX5_SET(pfcc_reg, in, device_stall_critical_watermark, pfc_preven_critical);
+ MLX5_SET(pfcc_reg, in, device_stall_minor_watermark, pfc_preven_minor);
+
+ return mlx5_core_access_reg(dev, in, sizeof(in), out,
+ sizeof(out), MLX5_REG_PFCC, 0, 1);
+}
+
+int mlx5_query_port_pfc_prevention(struct mlx5_core_dev *dev,
+ u16 *pfc_preven_critical)
+{
+ u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
+ int err;
+
+ err = mlx5_query_pfcc_reg(dev, out, sizeof(out));
+ if (err)
+ return err;
+
+ if (pfc_preven_critical)
+ *pfc_preven_critical = MLX5_GET(pfcc_reg, out,
+ device_stall_critical_watermark);
+
+ return 0;
+}
+
int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx)
{
u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
@@ -538,13 +581,10 @@ int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx)
int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
{
- u32 in[MLX5_ST_SZ_DW(pfcc_reg)] = {0};
u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
int err;
- MLX5_SET(pfcc_reg, in, local_port, 1);
- err = mlx5_core_access_reg(dev, in, sizeof(in), out,
- sizeof(out), MLX5_REG_PFCC, 0, 0);
+ err = mlx5_query_pfcc_reg(dev, out, sizeof(out));
if (err)
return err;
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 3e5363f..966cd5f 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -7755,7 +7755,11 @@ struct mlx5_ifc_pifr_reg_bits {
struct mlx5_ifc_pfcc_reg_bits {
u8 reserved_at_0[0x8];
u8 local_port[0x8];
- u8 reserved_at_10[0x10];
+ u8 reserved_at_10[0xb];
+ u8 ppan_mask_n[0x1];
+ u8 minor_stall_mask[0x1];
+ u8 critical_stall_mask[0x1];
+ u8 reserved_at_1e[0x2];
u8 ppan[0x4];
u8 reserved_at_24[0x4];
@@ -7765,17 +7769,22 @@ struct mlx5_ifc_pfcc_reg_bits {
u8 pptx[0x1];
u8 aptx[0x1];
- u8 reserved_at_42[0x6];
+ u8 pptx_mask_n[0x1];
+ u8 reserved_at_43[0x5];
u8 pfctx[0x8];
u8 reserved_at_50[0x10];
u8 pprx[0x1];
u8 aprx[0x1];
- u8 reserved_at_62[0x6];
+ u8 pprx_mask_n[0x1];
+ u8 reserved_at_63[0x5];
u8 pfcrx[0x8];
u8 reserved_at_70[0x10];
- u8 reserved_at_80[0x80];
+ u8 device_stall_minor_watermark[0x10];
+ u8 device_stall_critical_watermark[0x10];
+
+ u8 reserved_at_a0[0x60];
};
struct mlx5_ifc_pelc_reg_bits {
@@ -7816,7 +7825,10 @@ struct mlx5_ifc_peir_reg_bits {
};
struct mlx5_ifc_pcam_enhanced_features_bits {
- u8 reserved_at_0[0x7b];
+ u8 reserved_at_0[0x76];
+
+ u8 pfcc_mask[0x1];
+ u8 reserved_at_77[0x4];
u8 rx_buffer_fullness_counters[0x1];
u8 ptys_connector_type[0x1];
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
index 035f0d4..139a228 100644
--- a/include/linux/mlx5/port.h
+++ b/include/linux/mlx5/port.h
@@ -147,6 +147,11 @@ int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
int mlx5_query_port_pause(struct mlx5_core_dev *dev,
u32 *rx_pause, u32 *tx_pause);
+int mlx5_set_port_pfc_prevention(struct mlx5_core_dev *dev, u16 pfc_preven_critical,
+ u16 pfc_preven_minor);
+int mlx5_query_port_pfc_prevention(struct mlx5_core_dev *dev,
+ u16 *pfc_preven_critical);
+
int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx);
int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx,
u8 *pfc_en_rx);
--
1.8.3.1
Powered by blists - more mailing lists