net/mlx5: SF, Fix show state inactive when its inactivated
authorParav Pandit <parav@nvidia.com>
Fri, 7 May 2021 07:08:47 +0000 (10:08 +0300)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 19 May 2021 06:01:29 +0000 (23:01 -0700)
When a SF is inactivated and when it is in a TEARDOWN_REQUEST
state, driver still returns its state as active. This is incorrect.
Fix it by treating TEARDOWN_REQEUST as inactive state. When a SF
is still attached to the driver, on user request to reactivate EINVAL
error is returned. Inform user about it with better code EBUSY and
informative error message.

Fixes: 6a3273217469 ("net/mlx5: SF, Port function state change support")
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c

index a8e73c9ed1eae11a2e797d117415c2e9edf87bbd..1be0487693094a4ab613005383ba18118e7672bd 100644 (file)
@@ -136,10 +136,10 @@ static enum devlink_port_fn_state mlx5_sf_to_devlink_state(u8 hw_state)
        switch (hw_state) {
        case MLX5_VHCA_STATE_ACTIVE:
        case MLX5_VHCA_STATE_IN_USE:
-       case MLX5_VHCA_STATE_TEARDOWN_REQUEST:
                return DEVLINK_PORT_FN_STATE_ACTIVE;
        case MLX5_VHCA_STATE_INVALID:
        case MLX5_VHCA_STATE_ALLOCATED:
+       case MLX5_VHCA_STATE_TEARDOWN_REQUEST:
        default:
                return DEVLINK_PORT_FN_STATE_INACTIVE;
        }
@@ -192,14 +192,17 @@ sf_err:
        return err;
 }
 
-static int mlx5_sf_activate(struct mlx5_core_dev *dev, struct mlx5_sf *sf)
+static int mlx5_sf_activate(struct mlx5_core_dev *dev, struct mlx5_sf *sf,
+                           struct netlink_ext_ack *extack)
 {
        int err;
 
        if (mlx5_sf_is_active(sf))
                return 0;
-       if (sf->hw_state != MLX5_VHCA_STATE_ALLOCATED)
-               return -EINVAL;
+       if (sf->hw_state != MLX5_VHCA_STATE_ALLOCATED) {
+               NL_SET_ERR_MSG_MOD(extack, "SF is inactivated but it is still attached");
+               return -EBUSY;
+       }
 
        err = mlx5_cmd_sf_enable_hca(dev, sf->hw_fn_id);
        if (err)
@@ -226,7 +229,8 @@ static int mlx5_sf_deactivate(struct mlx5_core_dev *dev, struct mlx5_sf *sf)
 
 static int mlx5_sf_state_set(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
                             struct mlx5_sf *sf,
-                            enum devlink_port_fn_state state)
+                            enum devlink_port_fn_state state,
+                            struct netlink_ext_ack *extack)
 {
        int err = 0;
 
@@ -234,7 +238,7 @@ static int mlx5_sf_state_set(struct mlx5_core_dev *dev, struct mlx5_sf_table *ta
        if (state == mlx5_sf_to_devlink_state(sf->hw_state))
                goto out;
        if (state == DEVLINK_PORT_FN_STATE_ACTIVE)
-               err = mlx5_sf_activate(dev, sf);
+               err = mlx5_sf_activate(dev, sf, extack);
        else if (state == DEVLINK_PORT_FN_STATE_INACTIVE)
                err = mlx5_sf_deactivate(dev, sf);
        else
@@ -265,7 +269,7 @@ int mlx5_devlink_sf_port_fn_state_set(struct devlink *devlink, struct devlink_po
                goto out;
        }
 
-       err = mlx5_sf_state_set(dev, table, sf, state);
+       err = mlx5_sf_state_set(dev, table, sf, state, extack);
 out:
        mlx5_sf_table_put(table);
        return err;