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

Commit 948e306d authored by Rony Efraim's avatar Rony Efraim Committed by David S. Miller
Browse files

net/mlx4: Add VF link state support



Add support to change the link state of VF (vPort)

Signed-off-by: default avatarRony Efraim <ronye@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d8faf48
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/errno.h>

#include <linux/mlx4/cmd.h>
#include <linux/mlx4/device.h>
#include <linux/semaphore.h>
#include <rdma/ib_smi.h>

@@ -2178,7 +2179,54 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
	ivf->qos	= s_info->default_qos;
	ivf->tx_rate	= s_info->tx_rate;
	ivf->spoofchk	= s_info->spoofchk;
	ivf->linkstate	= s_info->link_state;

	return 0;
}
EXPORT_SYMBOL_GPL(mlx4_get_vf_config);

int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_vport_state *s_info;
	struct mlx4_vport_oper_state *vp_oper;
	int slave;
	u8 link_stat_event;

	slave = mlx4_get_slave_indx(dev, vf);
	if (slave < 0)
		return -EINVAL;

	switch (link_state) {
	case IFLA_VF_LINK_STATE_AUTO:
		/* get current link state */
		if (!priv->sense.do_sense_port[port])
			link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
		else
			link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
	    break;

	case IFLA_VF_LINK_STATE_ENABLE:
		link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
	    break;

	case IFLA_VF_LINK_STATE_DISABLE:
		link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
	    break;

	default:
		mlx4_warn(dev, "unknown value for link_state %02x on slave %d port %d\n",
			  link_state, slave, port);
		return -EINVAL;
	};
	/* update the admin & oper state on the link state */
	s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
	vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
	s_info->link_state = link_state;
	vp_oper->state.link_state = link_state;

	/* send event */
	mlx4_gen_port_state_change_eqe(dev, slave, port, link_stat_event);
	return 0;
}
EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
+8 −0
Original line number Diff line number Diff line
@@ -2061,6 +2061,13 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_
	return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf);
}

static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_state)
{
	struct mlx4_en_priv *en_priv = netdev_priv(dev);
	struct mlx4_en_dev *mdev = en_priv->mdev;

	return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
}
static const struct net_device_ops mlx4_netdev_ops = {
	.ndo_open		= mlx4_en_open,
	.ndo_stop		= mlx4_en_close,
@@ -2101,6 +2108,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
	.ndo_set_vf_mac		= mlx4_en_set_vf_mac,
	.ndo_set_vf_vlan	= mlx4_en_set_vf_vlan,
	.ndo_set_vf_spoofchk	= mlx4_en_set_vf_spoofchk,
	.ndo_set_vf_link_state	= mlx4_en_set_vf_link_state,
	.ndo_get_vf_config	= mlx4_en_get_vf_config,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= mlx4_en_netpoll,
+7 −2
Original line number Diff line number Diff line
@@ -448,6 +448,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
	int i;
	enum slave_port_gen_event gen_event;
	unsigned long flags;
	struct mlx4_vport_state *s_info;

	while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) {
		/*
@@ -556,6 +557,8 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
						mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN"
							 " to slave: %d, port:%d\n",
							 __func__, i, port);
						s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
						if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state)
							mlx4_slave_event(dev, i, eqe);
					} else {  /* IB port */
						set_and_calc_slave_port_state(dev, i, port,
@@ -580,6 +583,8 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
					for (i = 0; i < dev->num_slaves; i++) {
						if (i == mlx4_master_func_num(dev))
							continue;
						s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
						if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state)
							mlx4_slave_event(dev, i, eqe);
					}
				else /* IB port */
+8 −0
Original line number Diff line number Diff line
@@ -830,8 +830,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
	u8 port_type;
	u16 short_field;
	int err;
	int admin_link_state;

#define MLX4_VF_PORT_NO_LINK_SENSE_MASK	0xE0
#define MLX4_PORT_LINK_UP_MASK		0x80
#define QUERY_PORT_CUR_MAX_PKEY_OFFSET	0x0c
#define QUERY_PORT_CUR_MAX_GID_OFFSET	0x0e

@@ -861,6 +863,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
		/* set port type to currently operating port type */
		port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3);

		admin_link_state = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.link_state;
		if (IFLA_VF_LINK_STATE_ENABLE == admin_link_state)
			port_type |= MLX4_PORT_LINK_UP_MASK;
		else if (IFLA_VF_LINK_STATE_DISABLE == admin_link_state)
			port_type &= ~MLX4_PORT_LINK_UP_MASK;

		MLX4_PUT(outbox->buf, port_type,
			 QUERY_PORT_SUPPORTED_TYPE_OFFSET);

+1 −0
Original line number Diff line number Diff line
@@ -482,6 +482,7 @@ struct mlx4_vport_state {
	u8  default_qos;
	u32 tx_rate;
	bool spoofchk;
	u32 link_state;
};

struct mlx4_vf_admin_state {
Loading