From: Huy Nguyen
Current implementation does not read the setting
directly from FW when ieee_getets is called.
Solution:
1. Read the ETS settings directly from firmware.
2. For tc_tsa:
a. Initialize tc_tsa to vendor IEEE_8021QAZ_TSA_VENDOR at netdev
creation.
b. When reading ETS setting from FW, if the traffic class bandwidth
is less than 100, set tc_tsa to IEEE_8021QAZ_TSA_ETS. This
implementation solves the scenarios when the DCBX is in FW control
and willing bit is on which means the ETS setting is dictated
by remote switch.
Signed-off-by: Huy Nguyen
Signed-off-by: Saeed Mahameed
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 6 ++--
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 35 ++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 26
3 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h
b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 6919e3c..0d41287 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -203,9 +203,6 @@ struct mlx5e_params {
u8 toeplitz_hash_key[40];
u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
bool vlan_strip_disable;
-#ifdef CONFIG_MLX5_CORE_EN_DCB
- struct ieee_ets ets;
-#endif
bool rx_am_enabled;
};
@@ -226,6 +223,9 @@ enum {
struct mlx5e_dcbx {
struct mlx5e_cee_configcee_cfg; /* pending configuration */
+
+ /* The only setting that cannot be read from FW */
+ u8 tc_tsa[IEEE_8021QAZ_MAX_TCS];
};
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index b161dd9..1c10f9c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -45,12 +45,31 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device
*netdev,
struct ieee_ets *ets)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5_core_dev *mdev = priv->mdev;
+ int i;
+ int err = 0;
if (!MLX5_CAP_GEN(priv->mdev, ets))
return -ENOTSUPP;
- memcpy(ets, >params.ets, sizeof(*ets));
- return 0;
+ ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
+ for (i = 0; i < ets->ets_cap; i++) {
+ err = mlx5_query_port_prio_tc(mdev, i, >prio_tc[i]);
+ if (err)
+ return err;
+ }
+
+ for (i = 0; i < ets->ets_cap; i++) {
+ err = mlx5_query_port_tc_bw_alloc(mdev, i, >tc_tx_bw[i]);
+ if (err)
+ return err;
+ if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC)
+ priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
+ }
+
+ memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa));
+
+ return err;
}
enum {
@@ -127,7 +146,14 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv,
struct ieee_ets *ets)
if (err)
return err;
- return mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw);
+ err = mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw);
+
+ if (err)
+ return err;
+
+ memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
+
+ return err;
}
static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
@@ -181,9 +207,6 @@ static int mlx5e_dcbnl_ieee_setets(struct net_device
*netdev,
if (err)
return err;
- memcpy(>params.ets, ets, sizeof(*ets));
- priv->params.ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
-
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 03586ee..8f17928 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2875,17 +2875,23 @@ u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)
static void mlx5e_ets_init(struct mlx5e_priv *priv)
{
int i;
+ struct ieee_ets ets;
- priv->params.ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
- for (i = 0; i < priv->params.ets.ets_cap; i++) {
- priv->params.ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
- priv->params.ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
- priv->params.ets.prio_tc[i] = i;
+ memset(, 0, sizeof(ets));
+ ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
+ for (i = 0; i < ets.ets_cap; i++) {
+ ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
+ ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
+ ets.prio_tc[i] = i;
}
+ memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa));
+
/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for