Commit 8d88e198 authored by Jianbo Liu's avatar Jianbo Liu Committed by Saeed Mahameed

net/mlx5e: Consider aggregated port speed during rate configuration

When LAG is configured, functions (PF,VF,SF) can utilize the maximum
aggregated link speed for transmission. Currently the aggregated link
speed is not considered.

Hence, improve it to use the aggregated link speed by referring to the
physical port's upper bonding device when LAG is configured.
Signed-off-by: default avatarJianbo Liu <jianbol@nvidia.com>
Reviewed-by: default avatarParav Pandit <parav@nvidia.com>
Reviewed-by: default avatarDragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 7c35cd83
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ /* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#include "eswitch.h" #include "eswitch.h"
#include "lib/mlx5.h"
#include "esw/qos.h" #include "esw/qos.h"
#include "en/port.h" #include "en/port.h"
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
...@@ -701,6 +702,70 @@ int mlx5_esw_qos_set_vport_rate(struct mlx5_eswitch *esw, struct mlx5_vport *vpo ...@@ -701,6 +702,70 @@ int mlx5_esw_qos_set_vport_rate(struct mlx5_eswitch *esw, struct mlx5_vport *vpo
return err; return err;
} }
static u32 mlx5_esw_qos_lag_link_speed_get_locked(struct mlx5_core_dev *mdev)
{
struct ethtool_link_ksettings lksettings;
struct net_device *slave, *master;
u32 speed = SPEED_UNKNOWN;
/* Lock ensures a stable reference to master and slave netdevice
* while port speed of master is queried.
*/
ASSERT_RTNL();
slave = mlx5_uplink_netdev_get(mdev);
if (!slave)
goto out;
master = netdev_master_upper_dev_get(slave);
if (master && !__ethtool_get_link_ksettings(master, &lksettings))
speed = lksettings.base.speed;
out:
return speed;
}
static int mlx5_esw_qos_max_link_speed_get(struct mlx5_core_dev *mdev, u32 *link_speed_max,
bool hold_rtnl_lock, struct netlink_ext_ack *extack)
{
int err;
if (!mlx5_lag_is_active(mdev))
goto skip_lag;
if (hold_rtnl_lock)
rtnl_lock();
*link_speed_max = mlx5_esw_qos_lag_link_speed_get_locked(mdev);
if (hold_rtnl_lock)
rtnl_unlock();
if (*link_speed_max != (u32)SPEED_UNKNOWN)
return 0;
skip_lag:
err = mlx5_port_max_linkspeed(mdev, link_speed_max);
if (err)
NL_SET_ERR_MSG_MOD(extack, "Failed to get link maximum speed");
return err;
}
static int mlx5_esw_qos_link_speed_verify(struct mlx5_core_dev *mdev,
const char *name, u32 link_speed_max,
u64 value, struct netlink_ext_ack *extack)
{
if (value > link_speed_max) {
pr_err("%s rate value %lluMbps exceed link maximum speed %u.\n",
name, value, link_speed_max);
NL_SET_ERR_MSG_MOD(extack, "TX rate value exceed link maximum speed");
return -EINVAL;
}
return 0;
}
int mlx5_esw_qos_modify_vport_rate(struct mlx5_eswitch *esw, u16 vport_num, u32 rate_mbps) int mlx5_esw_qos_modify_vport_rate(struct mlx5_eswitch *esw, u16 vport_num, u32 rate_mbps)
{ {
u32 ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; u32 ctx[MLX5_ST_SZ_DW(scheduling_context)] = {};
...@@ -744,12 +809,6 @@ static int esw_qos_devlink_rate_to_mbps(struct mlx5_core_dev *mdev, const char * ...@@ -744,12 +809,6 @@ static int esw_qos_devlink_rate_to_mbps(struct mlx5_core_dev *mdev, const char *
u64 value; u64 value;
int err; int err;
err = mlx5_port_max_linkspeed(mdev, &link_speed_max);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed to get link maximum speed");
return err;
}
value = div_u64_rem(*rate, MLX5_LINKSPEED_UNIT, &remainder); value = div_u64_rem(*rate, MLX5_LINKSPEED_UNIT, &remainder);
if (remainder) { if (remainder) {
pr_err("%s rate value %lluBps not in link speed units of 1Mbps.\n", pr_err("%s rate value %lluBps not in link speed units of 1Mbps.\n",
...@@ -758,12 +817,13 @@ static int esw_qos_devlink_rate_to_mbps(struct mlx5_core_dev *mdev, const char * ...@@ -758,12 +817,13 @@ static int esw_qos_devlink_rate_to_mbps(struct mlx5_core_dev *mdev, const char *
return -EINVAL; return -EINVAL;
} }
if (value > link_speed_max) { err = mlx5_esw_qos_max_link_speed_get(mdev, &link_speed_max, true, extack);
pr_err("%s rate value %lluMbps exceed link maximum speed %u.\n", if (err)
name, value, link_speed_max); return err;
NL_SET_ERR_MSG_MOD(extack, "TX rate value exceed link maximum speed");
return -EINVAL; err = mlx5_esw_qos_link_speed_verify(mdev, name, link_speed_max, value, extack);
} if (err)
return err;
*rate = value; *rate = value;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment