Commit bc541621 authored by Saeed Mahameed's avatar Saeed Mahameed

net/mlx5e: Support ethtool cq mode

Add support for ethtool coalesce cq mode set and get.
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
parent b9241f54
...@@ -1148,9 +1148,12 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv, ...@@ -1148,9 +1148,12 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
struct ethtool_channels *ch); struct ethtool_channels *ch);
int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv, int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal); struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal);
int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv, int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal); struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack);
int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
struct ethtool_link_ksettings *link_ksettings); struct ethtool_link_ksettings *link_ksettings);
int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
......
...@@ -511,7 +511,8 @@ static int mlx5e_set_channels(struct net_device *dev, ...@@ -511,7 +511,8 @@ static int mlx5e_set_channels(struct net_device *dev,
} }
int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv, int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal) struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal)
{ {
struct dim_cq_moder *rx_moder, *tx_moder; struct dim_cq_moder *rx_moder, *tx_moder;
...@@ -528,6 +529,11 @@ int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv, ...@@ -528,6 +529,11 @@ int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
coal->tx_max_coalesced_frames = tx_moder->pkts; coal->tx_max_coalesced_frames = tx_moder->pkts;
coal->use_adaptive_tx_coalesce = priv->channels.params.tx_dim_enabled; coal->use_adaptive_tx_coalesce = priv->channels.params.tx_dim_enabled;
kernel_coal->use_cqe_mode_rx =
MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_BASED_MODER);
kernel_coal->use_cqe_mode_tx =
MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_CQE_BASED_MODER);
return 0; return 0;
} }
...@@ -538,7 +544,7 @@ static int mlx5e_get_coalesce(struct net_device *netdev, ...@@ -538,7 +544,7 @@ static int mlx5e_get_coalesce(struct net_device *netdev,
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_get_coalesce(priv, coal); return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
} }
#define MLX5E_MAX_COAL_TIME MLX5_MAX_CQ_PERIOD #define MLX5E_MAX_COAL_TIME MLX5_MAX_CQ_PERIOD
...@@ -578,14 +584,26 @@ mlx5e_set_priv_channels_rx_coalesce(struct mlx5e_priv *priv, struct ethtool_coal ...@@ -578,14 +584,26 @@ mlx5e_set_priv_channels_rx_coalesce(struct mlx5e_priv *priv, struct ethtool_coal
} }
} }
/* convert a boolean value of cq_mode to mlx5 period mode
* true : MLX5_CQ_PERIOD_MODE_START_FROM_CQE
* false : MLX5_CQ_PERIOD_MODE_START_FROM_EQE
*/
static int cqe_mode_to_period_mode(bool val)
{
return val ? MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
}
int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv, int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal) struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{ {
struct dim_cq_moder *rx_moder, *tx_moder; struct dim_cq_moder *rx_moder, *tx_moder;
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_params new_params; struct mlx5e_params new_params;
bool reset_rx, reset_tx; bool reset_rx, reset_tx;
bool reset = true; bool reset = true;
u8 cq_period_mode;
int err = 0; int err = 0;
if (!MLX5_CAP_GEN(mdev, cq_moderation)) if (!MLX5_CAP_GEN(mdev, cq_moderation))
...@@ -605,6 +623,12 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv, ...@@ -605,6 +623,12 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
return -ERANGE; return -ERANGE;
} }
if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) &&
!MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) {
NL_SET_ERR_MSG_MOD(extack, "cqe_mode_rx/tx is not supported on this device");
return -EOPNOTSUPP;
}
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
new_params = priv->channels.params; new_params = priv->channels.params;
...@@ -621,6 +645,18 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv, ...@@ -621,6 +645,18 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
reset_rx = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled; reset_rx = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled;
reset_tx = !!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled; reset_tx = !!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled;
cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_rx);
if (cq_period_mode != rx_moder->cq_period_mode) {
mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
reset_rx = true;
}
cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_tx);
if (cq_period_mode != tx_moder->cq_period_mode) {
mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
reset_tx = true;
}
if (reset_rx) { if (reset_rx) {
u8 mode = MLX5E_GET_PFLAG(&new_params, u8 mode = MLX5E_GET_PFLAG(&new_params,
MLX5E_PFLAG_RX_CQE_BASED_MODER); MLX5E_PFLAG_RX_CQE_BASED_MODER);
...@@ -656,9 +692,9 @@ static int mlx5e_set_coalesce(struct net_device *netdev, ...@@ -656,9 +692,9 @@ static int mlx5e_set_coalesce(struct net_device *netdev,
struct kernel_ethtool_coalesce *kernel_coal, struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_set_coalesce(priv, coal); return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
} }
static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev, static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
...@@ -2358,7 +2394,8 @@ static void mlx5e_get_rmon_stats(struct net_device *netdev, ...@@ -2358,7 +2394,8 @@ static void mlx5e_get_rmon_stats(struct net_device *netdev,
const struct ethtool_ops mlx5e_ethtool_ops = { const struct ethtool_ops mlx5e_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS | .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES | ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE, ETHTOOL_COALESCE_USE_ADAPTIVE |
ETHTOOL_COALESCE_USE_CQE,
.get_drvinfo = mlx5e_get_drvinfo, .get_drvinfo = mlx5e_get_drvinfo,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_link_ext_state = mlx5e_get_link_ext_state, .get_link_ext_state = mlx5e_get_link_ext_state,
......
...@@ -258,7 +258,7 @@ static int mlx5e_rep_get_coalesce(struct net_device *netdev, ...@@ -258,7 +258,7 @@ static int mlx5e_rep_get_coalesce(struct net_device *netdev,
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_get_coalesce(priv, coal); return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
} }
static int mlx5e_rep_set_coalesce(struct net_device *netdev, static int mlx5e_rep_set_coalesce(struct net_device *netdev,
...@@ -268,7 +268,7 @@ static int mlx5e_rep_set_coalesce(struct net_device *netdev, ...@@ -268,7 +268,7 @@ static int mlx5e_rep_set_coalesce(struct net_device *netdev,
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_set_coalesce(priv, coal); return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
} }
static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev) static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
......
...@@ -105,7 +105,7 @@ static int mlx5i_set_coalesce(struct net_device *netdev, ...@@ -105,7 +105,7 @@ static int mlx5i_set_coalesce(struct net_device *netdev,
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
return mlx5e_ethtool_set_coalesce(priv, coal); return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
} }
static int mlx5i_get_coalesce(struct net_device *netdev, static int mlx5i_get_coalesce(struct net_device *netdev,
...@@ -115,7 +115,7 @@ static int mlx5i_get_coalesce(struct net_device *netdev, ...@@ -115,7 +115,7 @@ static int mlx5i_get_coalesce(struct net_device *netdev,
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
return mlx5e_ethtool_get_coalesce(priv, coal); return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
} }
static int mlx5i_get_ts_info(struct net_device *netdev, static int mlx5i_get_ts_info(struct net_device *netdev,
......
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