mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 04:56:13 +02:00
net/mlx5e: Extend TC max ratelimit using max_bw_value_msb
The per-TC rate limit was restricted to 255 Gbps due to the 8-bit max_bw_value field in the QETC register. This limit is insufficient for newer, higher-bandwidth NICs. Extend the rate limit by using the full 16-bit max_bw_value field. This allows the finer 100Mbps granularity to be used for rates up to ~6.5 Tbps, instead of switching to 1Gbps granularity at higher rates. The extended range is only used when the device advertises support via the qetcr_qshr_max_bw_val_msb capability bit in the QCAM register. Signed-off-by: Alexei Lazar <alazar@nvidia.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Gal Pressman <gal@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20260203073021.1710806-2-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
23fb09db9e
commit
3e5aa52b45
|
|
@ -29,6 +29,10 @@ struct mlx5e_dcbx {
|
|||
u32 cable_len;
|
||||
u32 xoff;
|
||||
u16 port_buff_cell_sz;
|
||||
|
||||
/* Upper limit for 100Mbps and 1Gbps in Kbps units */
|
||||
u64 upper_limit_100mbps;
|
||||
u64 upper_limit_gbps;
|
||||
};
|
||||
|
||||
#define MLX5E_MAX_DSCP (64)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,20 @@ enum {
|
|||
MLX5_DCB_CHG_NO_RESET,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int scale;
|
||||
const char *units_str;
|
||||
} mlx5e_bw_units[] = {
|
||||
[MLX5_100_MBPS_UNIT] = {
|
||||
.scale = 100,
|
||||
.units_str = "Mbps",
|
||||
},
|
||||
[MLX5_GBPS_UNIT] = {
|
||||
.scale = 1,
|
||||
.units_str = "Gbps",
|
||||
},
|
||||
};
|
||||
|
||||
#define MLX5_DSCP_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, qcam_reg) && \
|
||||
MLX5_CAP_QCAM_REG(mdev, qpts) && \
|
||||
MLX5_CAP_QCAM_REG(mdev, qpdpm))
|
||||
|
|
@ -559,7 +573,7 @@ static int mlx5e_dcbnl_ieee_getmaxrate(struct net_device *netdev,
|
|||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
|
||||
u16 max_bw_value[IEEE_8021QAZ_MAX_TCS];
|
||||
u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
|
||||
int err;
|
||||
int i;
|
||||
|
|
@ -594,57 +608,41 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
|
|||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
|
||||
u16 max_bw_value[IEEE_8021QAZ_MAX_TCS];
|
||||
u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
|
||||
u64 upper_limit_100mbps;
|
||||
u64 upper_limit_gbps;
|
||||
int i;
|
||||
struct {
|
||||
int scale;
|
||||
const char *units_str;
|
||||
} units[] = {
|
||||
[MLX5_100_MBPS_UNIT] = {
|
||||
.scale = 100,
|
||||
.units_str = "Mbps",
|
||||
},
|
||||
[MLX5_GBPS_UNIT] = {
|
||||
.scale = 1,
|
||||
.units_str = "Gbps",
|
||||
},
|
||||
};
|
||||
|
||||
memset(max_bw_value, 0, sizeof(max_bw_value));
|
||||
memset(max_bw_unit, 0, sizeof(max_bw_unit));
|
||||
upper_limit_100mbps = U8_MAX * MLX5E_100MB_TO_KB;
|
||||
upper_limit_gbps = U8_MAX * MLX5E_1GB_TO_KB;
|
||||
|
||||
for (i = 0; i <= mlx5_max_tc(mdev); i++) {
|
||||
if (!maxrate->tc_maxrate[i]) {
|
||||
u64 rate = maxrate->tc_maxrate[i];
|
||||
|
||||
if (!rate) {
|
||||
max_bw_unit[i] = MLX5_BW_NO_LIMIT;
|
||||
continue;
|
||||
}
|
||||
if (maxrate->tc_maxrate[i] <= upper_limit_100mbps) {
|
||||
max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
|
||||
MLX5E_100MB_TO_KB);
|
||||
if (rate <= priv->dcbx.upper_limit_100mbps) {
|
||||
max_bw_value[i] = div_u64(rate, MLX5E_100MB_TO_KB);
|
||||
max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
|
||||
max_bw_unit[i] = MLX5_100_MBPS_UNIT;
|
||||
} else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
|
||||
max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
|
||||
MLX5E_1GB_TO_KB);
|
||||
} else if (rate <= priv->dcbx.upper_limit_gbps) {
|
||||
max_bw_value[i] = div_u64(rate, MLX5E_1GB_TO_KB);
|
||||
max_bw_unit[i] = MLX5_GBPS_UNIT;
|
||||
} else {
|
||||
netdev_err(netdev,
|
||||
"tc_%d maxrate %llu Kbps exceeds limit %llu\n",
|
||||
i, maxrate->tc_maxrate[i],
|
||||
upper_limit_gbps);
|
||||
i, rate, priv->dcbx.upper_limit_gbps);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
u8 unit = max_bw_unit[i];
|
||||
|
||||
netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i,
|
||||
max_bw_value[i] * units[max_bw_unit[i]].scale,
|
||||
units[max_bw_unit[i]].units_str);
|
||||
max_bw_value[i] * mlx5e_bw_units[unit].scale,
|
||||
mlx5e_bw_units[unit].units_str);
|
||||
}
|
||||
|
||||
return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
|
||||
|
|
@ -1268,6 +1266,8 @@ static u16 mlx5e_query_port_buffers_cell_size(struct mlx5e_priv *priv)
|
|||
void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_dcbx *dcbx = &priv->dcbx;
|
||||
bool max_bw_msb_supported;
|
||||
u16 type_max;
|
||||
|
||||
mlx5e_trust_initialize(priv);
|
||||
|
||||
|
|
@ -1285,5 +1285,11 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
|
|||
priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv);
|
||||
priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN;
|
||||
|
||||
max_bw_msb_supported = MLX5_CAP_QCAM_FEATURE(priv->mdev,
|
||||
qetcr_qshr_max_bw_val_msb);
|
||||
type_max = max_bw_msb_supported ? U16_MAX : U8_MAX;
|
||||
priv->dcbx.upper_limit_100mbps = type_max * MLX5E_100MB_TO_KB;
|
||||
priv->dcbx.upper_limit_gbps = type_max * MLX5E_1GB_TO_KB;
|
||||
|
||||
mlx5e_ets_init(priv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,10 +345,10 @@ int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw);
|
|||
int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
|
||||
u8 tc, u8 *bw_pct);
|
||||
int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
|
||||
u8 *max_bw_value,
|
||||
u16 *max_bw_value,
|
||||
u8 *max_bw_unit);
|
||||
int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
|
||||
u8 *max_bw_value,
|
||||
u16 *max_bw_value,
|
||||
u8 *max_bw_unit);
|
||||
int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode);
|
||||
int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode);
|
||||
|
|
|
|||
|
|
@ -773,7 +773,7 @@ int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
|
|||
}
|
||||
|
||||
int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
|
||||
u8 *max_bw_value,
|
||||
u16 *max_bw_value,
|
||||
u8 *max_bw_units)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {0};
|
||||
|
|
@ -796,7 +796,7 @@ int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
|
|||
}
|
||||
|
||||
int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
|
||||
u8 *max_bw_value,
|
||||
u16 *max_bw_value,
|
||||
u8 *max_bw_units)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(qetc_reg)];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user