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

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
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mlx4/cmd.h> #include <linux/mlx4/cmd.h>
#include <linux/mlx4/device.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <rdma/ib_smi.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 ...@@ -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->qos = s_info->default_qos;
ivf->tx_rate = s_info->tx_rate; ivf->tx_rate = s_info->tx_rate;
ivf->spoofchk = s_info->spoofchk; ivf->spoofchk = s_info->spoofchk;
ivf->linkstate = s_info->link_state;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mlx4_get_vf_config); 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);
...@@ -2061,6 +2061,13 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_ ...@@ -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); 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 = { static const struct net_device_ops mlx4_netdev_ops = {
.ndo_open = mlx4_en_open, .ndo_open = mlx4_en_open,
.ndo_stop = mlx4_en_close, .ndo_stop = mlx4_en_close,
...@@ -2101,6 +2108,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { ...@@ -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_mac = mlx4_en_set_vf_mac,
.ndo_set_vf_vlan = mlx4_en_set_vf_vlan, .ndo_set_vf_vlan = mlx4_en_set_vf_vlan,
.ndo_set_vf_spoofchk = mlx4_en_set_vf_spoofchk, .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, .ndo_get_vf_config = mlx4_en_get_vf_config,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = mlx4_en_netpoll, .ndo_poll_controller = mlx4_en_netpoll,
......
...@@ -448,6 +448,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -448,6 +448,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
int i; int i;
enum slave_port_gen_event gen_event; enum slave_port_gen_event gen_event;
unsigned long flags; unsigned long flags;
struct mlx4_vport_state *s_info;
while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) { while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) {
/* /*
...@@ -556,7 +557,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -556,7 +557,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN" mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN"
" to slave: %d, port:%d\n", " to slave: %d, port:%d\n",
__func__, i, port); __func__, i, port);
mlx4_slave_event(dev, i, eqe); 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 */ } else { /* IB port */
set_and_calc_slave_port_state(dev, i, port, set_and_calc_slave_port_state(dev, i, port,
MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN, MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN,
...@@ -580,7 +583,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -580,7 +583,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
for (i = 0; i < dev->num_slaves; i++) { for (i = 0; i < dev->num_slaves; i++) {
if (i == mlx4_master_func_num(dev)) if (i == mlx4_master_func_num(dev))
continue; continue;
mlx4_slave_event(dev, i, eqe); 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 */ else /* IB port */
/* port-up event will be sent to a slave when the /* port-up event will be sent to a slave when the
......
...@@ -830,8 +830,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -830,8 +830,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
u8 port_type; u8 port_type;
u16 short_field; u16 short_field;
int err; int err;
int admin_link_state;
#define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 #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_PKEY_OFFSET 0x0c
#define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e
...@@ -861,6 +863,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -861,6 +863,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
/* set port type to currently operating port type */ /* set port type to currently operating port type */
port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); 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, MLX4_PUT(outbox->buf, port_type,
QUERY_PORT_SUPPORTED_TYPE_OFFSET); QUERY_PORT_SUPPORTED_TYPE_OFFSET);
......
...@@ -482,6 +482,7 @@ struct mlx4_vport_state { ...@@ -482,6 +482,7 @@ struct mlx4_vport_state {
u8 default_qos; u8 default_qos;
u32 tx_rate; u32 tx_rate;
bool spoofchk; bool spoofchk;
u32 link_state;
}; };
struct mlx4_vf_admin_state { struct mlx4_vf_admin_state {
......
...@@ -237,7 +237,7 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); ...@@ -237,7 +237,7 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting);
int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf); int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf);
int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state);
#define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment