Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2facd95 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

mlx4: Implement port type setting via devlink interface



So far, there has been an mlx4-specific sysfs file allowing user to
change port type to either Ethernet of InfiniBand. This is very
inconvenient.

Allow to expose the same ability to set port type in a generic way
using devlink interface.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 09d4d087
Loading
Loading
Loading
Loading
+65 −21
Original line number Diff line number Diff line
@@ -1082,36 +1082,20 @@ static ssize_t show_port_type(struct device *dev,
	return strlen(buf);
}

static ssize_t set_port_type(struct device *dev,
			     struct device_attribute *attr,
			     const char *buf, size_t count)
static int __set_port_type(struct mlx4_port_info *info,
			   enum mlx4_port_type port_type)
{
	struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
						   port_attr);
	struct mlx4_dev *mdev = info->dev;
	struct mlx4_priv *priv = mlx4_priv(mdev);
	enum mlx4_port_type types[MLX4_MAX_PORTS];
	enum mlx4_port_type new_types[MLX4_MAX_PORTS];
	static DEFINE_MUTEX(set_port_type_mutex);
	int i;
	int err = 0;

	mutex_lock(&set_port_type_mutex);

	if (!strcmp(buf, "ib\n"))
		info->tmp_type = MLX4_PORT_TYPE_IB;
	else if (!strcmp(buf, "eth\n"))
		info->tmp_type = MLX4_PORT_TYPE_ETH;
	else if (!strcmp(buf, "auto\n"))
		info->tmp_type = MLX4_PORT_TYPE_AUTO;
	else {
		mlx4_err(mdev, "%s is not supported port type\n", buf);
		err = -EINVAL;
		goto err_out;
	}

	mlx4_stop_sense(mdev);
	mutex_lock(&priv->port_mutex);
	info->tmp_type = port_type;

	/* Possible type is always the one that was delivered */
	mdev->caps.possible_type[info->port] = info->tmp_type;

@@ -1153,6 +1137,37 @@ static ssize_t set_port_type(struct device *dev,
out:
	mlx4_start_sense(mdev);
	mutex_unlock(&priv->port_mutex);

	return err;
}

static ssize_t set_port_type(struct device *dev,
			     struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
						   port_attr);
	struct mlx4_dev *mdev = info->dev;
	enum mlx4_port_type port_type;
	static DEFINE_MUTEX(set_port_type_mutex);
	int err;

	mutex_lock(&set_port_type_mutex);

	if (!strcmp(buf, "ib\n")) {
		port_type = MLX4_PORT_TYPE_IB;
	} else if (!strcmp(buf, "eth\n")) {
		port_type = MLX4_PORT_TYPE_ETH;
	} else if (!strcmp(buf, "auto\n")) {
		port_type = MLX4_PORT_TYPE_AUTO;
	} else {
		mlx4_err(mdev, "%s is not supported port type\n", buf);
		err = -EINVAL;
		goto err_out;
	}

	err = __set_port_type(info, port_type);

err_out:
	mutex_unlock(&set_port_type_mutex);

@@ -3685,6 +3700,35 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
	return err;
}

static int mlx4_devlink_port_type_set(struct devlink_port *devlink_port,
				      enum devlink_port_type port_type)
{
	struct mlx4_port_info *info = container_of(devlink_port,
						   struct mlx4_port_info,
						   devlink_port);
	enum mlx4_port_type mlx4_port_type;

	switch (port_type) {
	case DEVLINK_PORT_TYPE_AUTO:
		mlx4_port_type = MLX4_PORT_TYPE_AUTO;
		break;
	case DEVLINK_PORT_TYPE_ETH:
		mlx4_port_type = MLX4_PORT_TYPE_ETH;
		break;
	case DEVLINK_PORT_TYPE_IB:
		mlx4_port_type = MLX4_PORT_TYPE_IB;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return __set_port_type(info, mlx4_port_type);
}

static const struct devlink_ops mlx4_devlink_ops = {
	.port_type_set	= mlx4_devlink_port_type_set,
};

static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct devlink *devlink;
@@ -3694,7 +3738,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)

	printk_once(KERN_INFO "%s", mlx4_version);

	devlink = devlink_alloc(NULL, sizeof(*priv));
	devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv));
	if (!devlink)
		return -ENOMEM;
	priv = devlink_priv(devlink);