]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/mlx5e: Support ethtool cq mode
authorSaeed Mahameed <saeedm@nvidia.com>
Wed, 15 Sep 2021 06:26:17 +0000 (23:26 -0700)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 17 Nov 2021 04:31:47 +0000 (20:31 -0800)
Add support for ethtool coalesce cq mode set and get.

Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c

index f0ac6b0d9653577eec06b982cbb98e2b3e7253df..48b12ee44b8d082eca8589c6ea9d58bee259d583 100644 (file)
@@ -1148,9 +1148,12 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
 int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
                               struct ethtool_channels *ch);
 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,
-                              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,
                                     struct ethtool_link_ksettings *link_ksettings);
 int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
index c2ea5fad48ddf28e7222592a7d37a9b563763c51..45bdfcb3dcc79f0f13787d853d1bfe4df72b1281 100644 (file)
@@ -511,7 +511,8 @@ static int mlx5e_set_channels(struct net_device *dev,
 }
 
 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;
 
@@ -528,6 +529,11 @@ int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
        coal->tx_max_coalesced_frames   = tx_moder->pkts;
        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;
 }
 
@@ -538,7 +544,7 @@ static int mlx5e_get_coalesce(struct net_device *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
@@ -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,
-                              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 mlx5_core_dev *mdev = priv->mdev;
        struct mlx5e_params new_params;
        bool reset_rx, reset_tx;
        bool reset = true;
+       u8 cq_period_mode;
        int err = 0;
 
        if (!MLX5_CAP_GEN(mdev, cq_moderation))
@@ -605,6 +623,12 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
                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);
        new_params = priv->channels.params;
 
@@ -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_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) {
                u8 mode = MLX5E_GET_PFLAG(&new_params,
                                          MLX5E_PFLAG_RX_CQE_BASED_MODER);
@@ -656,9 +692,9 @@ static int mlx5e_set_coalesce(struct net_device *netdev,
                              struct kernel_ethtool_coalesce *kernel_coal,
                              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,
@@ -2358,7 +2394,8 @@ static void mlx5e_get_rmon_stats(struct net_device *netdev,
 const struct ethtool_ops mlx5e_ethtool_ops = {
        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
                                     ETHTOOL_COALESCE_MAX_FRAMES |
-                                    ETHTOOL_COALESCE_USE_ADAPTIVE,
+                                    ETHTOOL_COALESCE_USE_ADAPTIVE |
+                                    ETHTOOL_COALESCE_USE_CQE,
        .get_drvinfo       = mlx5e_get_drvinfo,
        .get_link          = ethtool_op_get_link,
        .get_link_ext_state  = mlx5e_get_link_ext_state,
index e58a9ec4255322538e6cb847f8dddecc6659754c..8c81aeba07db8b7b538cc73df7fc0bfd55c54dbe 100644 (file)
@@ -258,7 +258,7 @@ static int mlx5e_rep_get_coalesce(struct net_device *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,
@@ -268,7 +268,7 @@ static int mlx5e_rep_set_coalesce(struct net_device *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)
index 962d41418ce71679443fd63786eb14814e32a166..f23e33ac9c6b22989fb410b854c5d9ef8d20de2f 100644 (file)
@@ -105,7 +105,7 @@ static int mlx5i_set_coalesce(struct net_device *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,
@@ -115,7 +115,7 @@ static int mlx5i_get_coalesce(struct net_device *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,