diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 48 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1 | ||||
| -rw-r--r-- | include/linux/mlx4/cmd.h | 2 |
6 files changed, 73 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 0e572a527154..ea1e03896353 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
| 40 | 40 | ||
| 41 | #include <linux/mlx4/cmd.h> | 41 | #include <linux/mlx4/cmd.h> |
| 42 | #include <linux/mlx4/device.h> | ||
| 42 | #include <linux/semaphore.h> | 43 | #include <linux/semaphore.h> |
| 43 | #include <rdma/ib_smi.h> | 44 | #include <rdma/ib_smi.h> |
| 44 | 45 | ||
| @@ -2178,7 +2179,54 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in | |||
| 2178 | ivf->qos = s_info->default_qos; | 2179 | ivf->qos = s_info->default_qos; |
| 2179 | ivf->tx_rate = s_info->tx_rate; | 2180 | ivf->tx_rate = s_info->tx_rate; |
| 2180 | ivf->spoofchk = s_info->spoofchk; | 2181 | ivf->spoofchk = s_info->spoofchk; |
| 2182 | ivf->linkstate = s_info->link_state; | ||
| 2181 | 2183 | ||
| 2182 | return 0; | 2184 | return 0; |
| 2183 | } | 2185 | } |
| 2184 | EXPORT_SYMBOL_GPL(mlx4_get_vf_config); | 2186 | EXPORT_SYMBOL_GPL(mlx4_get_vf_config); |
| 2187 | |||
| 2188 | int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state) | ||
| 2189 | { | ||
| 2190 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 2191 | struct mlx4_vport_state *s_info; | ||
| 2192 | struct mlx4_vport_oper_state *vp_oper; | ||
| 2193 | int slave; | ||
| 2194 | u8 link_stat_event; | ||
| 2195 | |||
| 2196 | slave = mlx4_get_slave_indx(dev, vf); | ||
| 2197 | if (slave < 0) | ||
| 2198 | return -EINVAL; | ||
| 2199 | |||
| 2200 | switch (link_state) { | ||
| 2201 | case IFLA_VF_LINK_STATE_AUTO: | ||
| 2202 | /* get current link state */ | ||
| 2203 | if (!priv->sense.do_sense_port[port]) | ||
| 2204 | link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE; | ||
| 2205 | else | ||
| 2206 | link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN; | ||
| 2207 | break; | ||
| 2208 | |||
| 2209 | case IFLA_VF_LINK_STATE_ENABLE: | ||
| 2210 | link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE; | ||
| 2211 | break; | ||
| 2212 | |||
| 2213 | case IFLA_VF_LINK_STATE_DISABLE: | ||
| 2214 | link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN; | ||
| 2215 | break; | ||
| 2216 | |||
| 2217 | default: | ||
| 2218 | mlx4_warn(dev, "unknown value for link_state %02x on slave %d port %d\n", | ||
| 2219 | link_state, slave, port); | ||
| 2220 | return -EINVAL; | ||
| 2221 | }; | ||
| 2222 | /* update the admin & oper state on the link state */ | ||
| 2223 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | ||
| 2224 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; | ||
| 2225 | s_info->link_state = link_state; | ||
| 2226 | vp_oper->state.link_state = link_state; | ||
| 2227 | |||
| 2228 | /* send event */ | ||
| 2229 | mlx4_gen_port_state_change_eqe(dev, slave, port, link_stat_event); | ||
| 2230 | return 0; | ||
| 2231 | } | ||
| 2232 | EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state); | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 89c47ea84b50..ade276cca0e6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
| @@ -2061,6 +2061,13 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_ | |||
| 2061 | return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf); | 2061 | return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf); |
| 2062 | } | 2062 | } |
| 2063 | 2063 | ||
| 2064 | static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_state) | ||
| 2065 | { | ||
| 2066 | struct mlx4_en_priv *en_priv = netdev_priv(dev); | ||
| 2067 | struct mlx4_en_dev *mdev = en_priv->mdev; | ||
| 2068 | |||
| 2069 | return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state); | ||
| 2070 | } | ||
| 2064 | static const struct net_device_ops mlx4_netdev_ops = { | 2071 | static const struct net_device_ops mlx4_netdev_ops = { |
| 2065 | .ndo_open = mlx4_en_open, | 2072 | .ndo_open = mlx4_en_open, |
| 2066 | .ndo_stop = mlx4_en_close, | 2073 | .ndo_stop = mlx4_en_close, |
| @@ -2101,6 +2108,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { | |||
| 2101 | .ndo_set_vf_mac = mlx4_en_set_vf_mac, | 2108 | .ndo_set_vf_mac = mlx4_en_set_vf_mac, |
| 2102 | .ndo_set_vf_vlan = mlx4_en_set_vf_vlan, | 2109 | .ndo_set_vf_vlan = mlx4_en_set_vf_vlan, |
| 2103 | .ndo_set_vf_spoofchk = mlx4_en_set_vf_spoofchk, | 2110 | .ndo_set_vf_spoofchk = mlx4_en_set_vf_spoofchk, |
| 2111 | .ndo_set_vf_link_state = mlx4_en_set_vf_link_state, | ||
| 2104 | .ndo_get_vf_config = mlx4_en_get_vf_config, | 2112 | .ndo_get_vf_config = mlx4_en_get_vf_config, |
| 2105 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2113 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 2106 | .ndo_poll_controller = mlx4_en_netpoll, | 2114 | .ndo_poll_controller = mlx4_en_netpoll, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 6000342f9725..7e042869ef0c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
| @@ -448,6 +448,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
| 448 | int i; | 448 | int i; |
| 449 | enum slave_port_gen_event gen_event; | 449 | enum slave_port_gen_event gen_event; |
| 450 | unsigned long flags; | 450 | unsigned long flags; |
| 451 | struct mlx4_vport_state *s_info; | ||
| 451 | 452 | ||
| 452 | while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) { | 453 | while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) { |
| 453 | /* | 454 | /* |
| @@ -556,7 +557,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
| 556 | mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN" | 557 | mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN" |
| 557 | " to slave: %d, port:%d\n", | 558 | " to slave: %d, port:%d\n", |
| 558 | __func__, i, port); | 559 | __func__, i, port); |
| 559 | mlx4_slave_event(dev, i, eqe); | 560 | s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state; |
| 561 | if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) | ||
| 562 | mlx4_slave_event(dev, i, eqe); | ||
| 560 | } else { /* IB port */ | 563 | } else { /* IB port */ |
| 561 | set_and_calc_slave_port_state(dev, i, port, | 564 | set_and_calc_slave_port_state(dev, i, port, |
| 562 | MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN, | 565 | 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 | for (i = 0; i < dev->num_slaves; i++) { | 583 | for (i = 0; i < dev->num_slaves; i++) { |
| 581 | if (i == mlx4_master_func_num(dev)) | 584 | if (i == mlx4_master_func_num(dev)) |
| 582 | continue; | 585 | continue; |
| 583 | mlx4_slave_event(dev, i, eqe); | 586 | s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state; |
| 587 | if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) | ||
| 588 | mlx4_slave_event(dev, i, eqe); | ||
| 584 | } | 589 | } |
| 585 | else /* IB port */ | 590 | else /* IB port */ |
| 586 | /* port-up event will be sent to a slave when the | 591 | /* port-up event will be sent to a slave when the |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 2c97901c6a6d..569bbe3e7403 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
| @@ -830,8 +830,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
| 830 | u8 port_type; | 830 | u8 port_type; |
| 831 | u16 short_field; | 831 | u16 short_field; |
| 832 | int err; | 832 | int err; |
| 833 | int admin_link_state; | ||
| 833 | 834 | ||
| 834 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 | 835 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 |
| 836 | #define MLX4_PORT_LINK_UP_MASK 0x80 | ||
| 835 | #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c | 837 | #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c |
| 836 | #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e | 838 | #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e |
| 837 | 839 | ||
| @@ -861,6 +863,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
| 861 | /* set port type to currently operating port type */ | 863 | /* set port type to currently operating port type */ |
| 862 | port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); | 864 | port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); |
| 863 | 865 | ||
| 866 | admin_link_state = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.link_state; | ||
| 867 | if (IFLA_VF_LINK_STATE_ENABLE == admin_link_state) | ||
| 868 | port_type |= MLX4_PORT_LINK_UP_MASK; | ||
| 869 | else if (IFLA_VF_LINK_STATE_DISABLE == admin_link_state) | ||
| 870 | port_type &= ~MLX4_PORT_LINK_UP_MASK; | ||
| 871 | |||
| 864 | MLX4_PUT(outbox->buf, port_type, | 872 | MLX4_PUT(outbox->buf, port_type, |
| 865 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 873 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
| 866 | 874 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index df15bb6631cc..75272935a3f7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -482,6 +482,7 @@ struct mlx4_vport_state { | |||
| 482 | u8 default_qos; | 482 | u8 default_qos; |
| 483 | u32 tx_rate; | 483 | u32 tx_rate; |
| 484 | bool spoofchk; | 484 | bool spoofchk; |
| 485 | u32 link_state; | ||
| 485 | }; | 486 | }; |
| 486 | 487 | ||
| 487 | struct mlx4_vf_admin_state { | 488 | struct mlx4_vf_admin_state { |
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index adf6e0648f20..8074a9711cf1 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h | |||
| @@ -237,7 +237,7 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); | |||
| 237 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); | 237 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); |
| 238 | int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); | 238 | int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); |
| 239 | int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf); | 239 | int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf); |
| 240 | 240 | int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state); | |
| 241 | 241 | ||
| 242 | #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) | 242 | #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) |
| 243 | 243 | ||
