]> www.infradead.org Git - users/jedix/linux-maple.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)
committerJakub Kicinski <kuba@kernel.org>
Thu, 21 Aug 2025 14:58:32 +0000 (07:58 -0700)
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>
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 5fe016e477b37e47054fec61ddd05c2c8a6bbd46..d166c0d5189e19b5d669bc67eb8faa4d59293ba9 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;
@@ -1252,7 +1259,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 b6d53db27cd573da8c68816afc790adc39a3a1b8..9d3504f5abfab26e7b42e0129d52f5c006aff48d 100644 (file)
@@ -367,6 +367,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 549f1066d2a508cf2048d428c4d60588ce8deacc..2d7adf7444ba29f722e847b6722f00b351efe6f4 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);