]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net/mlx5e: Query FW for buffer ownership
authorAlexei Lazar <alazar@nvidia.com>
Wed, 20 Aug 2025 13:32:08 +0000 (16:32 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:31:15 +0000 (16:31 +0200)
[ Upstream commit 451d2849ea66659040b59ae3cb7e50cc97404733 ]

The SW currently saves local buffer ownership when setting
the buffer.
This means that the SW assumes it has ownership of the buffer
after the command is set.

If setting the buffer fails and we remain in FW ownership,
the local buffer ownership state incorrectly remains as SW-owned.
This leads to incorrect behavior in subsequent PFC commands,
causing failures.

Instead of saving local buffer ownership in SW,
query the FW for buffer ownership when setting the buffer.
This ensures that the buffer ownership state is accurately
reflected, avoiding the issues caused by incorrect ownership
states.

Fixes: ecdf2dadee8e ("net/mlx5e: Receive buffer support for DCBX")
Signed-off-by: Alexei Lazar <alazar@nvidia.com>
Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20250820133209.389065-8-mbloch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/en/dcbnl.h
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlx5/core/port.c

index b59aee75de94e21e3d56cae468ff3d35f4781877..2c98a5299df3373994c7adf5f7db765bd1976496 100644 (file)
@@ -26,7 +26,6 @@ struct mlx5e_dcbx {
        u8                         cap;
 
        /* Buffer configuration */
-       bool                       manual_buffer;
        u32                        cable_len;
        u32                        xoff;
        u16                        port_buff_cell_sz;
index 8705cffc747ffbaeb08186fde904c5f30fbab438..b08328fe1aa30038ddee03190a7feef378869c99 100644 (file)
@@ -362,6 +362,7 @@ static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,
 static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
                                   struct ieee_pfc *pfc)
 {
+       u8 buffer_ownership = MLX5_BUF_OWNERSHIP_UNKNOWN;
        struct mlx5e_priv *priv = netdev_priv(dev);
        struct mlx5_core_dev *mdev = priv->mdev;
        u32 old_cable_len = priv->dcbx.cable_len;
@@ -389,7 +390,14 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
 
        if (MLX5_BUFFER_SUPPORTED(mdev)) {
                pfc_new.pfc_en = (changed & MLX5E_PORT_BUFFER_PFC) ? pfc->pfc_en : curr_pfc_en;
-               if (priv->dcbx.manual_buffer)
+               ret = mlx5_query_port_buffer_ownership(mdev,
+                                                      &buffer_ownership);
+               if (ret)
+                       netdev_err(dev,
+                                  "%s, Failed to get buffer ownership: %d\n",
+                                  __func__, ret);
+
+               if (buffer_ownership == MLX5_BUF_OWNERSHIP_SW_OWNED)
                        ret = mlx5e_port_manual_buffer_config(priv, changed,
                                                              dev->mtu, &pfc_new,
                                                              NULL, NULL);
@@ -982,7 +990,6 @@ static int mlx5e_dcbnl_setbuffer(struct net_device *dev,
        if (!changed)
                return 0;
 
-       priv->dcbx.manual_buffer = true;
        err = mlx5e_port_manual_buffer_config(priv, changed, dev->mtu, NULL,
                                              buffer_size, prio2buffer);
        return err;
@@ -1250,7 +1257,6 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
                priv->dcbx.cap |= DCB_CAP_DCBX_HOST;
 
        priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv);
-       priv->dcbx.manual_buffer = false;
        priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN;
 
        mlx5e_ets_init(priv);
index 52c9a196728ddb80de70a5e1979a81242215fc3c..dc6965f6746ec261e9617e7fbaa560b38dd6e92e 100644 (file)
@@ -351,6 +351,8 @@ int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
 int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
 int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state);
 int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state);
+int mlx5_query_port_buffer_ownership(struct mlx5_core_dev *mdev,
+                                    u8 *buffer_ownership);
 int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio);
 int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
 
index dee4e44e22741f196f7d0c87b45431c69f52c921..389b34d56b751aff086f6278f9350e493275b78c 100644 (file)
@@ -968,6 +968,26 @@ int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state)
        return err;
 }
 
+int mlx5_query_port_buffer_ownership(struct mlx5_core_dev *mdev,
+                                    u8 *buffer_ownership)
+{
+       u32 out[MLX5_ST_SZ_DW(pfcc_reg)] = {};
+       int err;
+
+       if (!MLX5_CAP_PCAM_FEATURE(mdev, buffer_ownership)) {
+               *buffer_ownership = MLX5_BUF_OWNERSHIP_UNKNOWN;
+               return 0;
+       }
+
+       err = mlx5_query_pfcc_reg(mdev, out, sizeof(out));
+       if (err)
+               return err;
+
+       *buffer_ownership = MLX5_GET(pfcc_reg, out, buf_ownership);
+
+       return 0;
+}
+
 int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio)
 {
        int sz = MLX5_ST_SZ_BYTES(qpdpm_reg);